home *** CD-ROM | disk | FTP | other *** search
/ Aminet 48 / Aminet 48 (2002)(GTI - Schatztruhe)[!][Apr 2002].iso / Aminet / text / edit / vim60src.lha / Vim / vim60 / src / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-09-21  |  71.7 KB  |  2,813 lines

  1. /* vi:set ts=8 sts=4 sw=4:
  2.  *
  3.  * VIM - Vi IMproved    by Bram Moolenaar
  4.  *
  5.  * Do ":help uganda"  in Vim to read copying and usage conditions.
  6.  * Do ":help credits" in Vim to see a list of people who contributed.
  7.  * See README.txt for an overview of the Vim source code.
  8.  */
  9.  
  10. #if defined(MSDOS) || defined(WIN32) || defined(_WIN64)
  11. # include <io.h>        /* for close() and dup() */
  12. #endif
  13.  
  14. #define EXTERN
  15. #include "vim.h"
  16.  
  17. #ifdef SPAWNO
  18. # include <spawno.h>        /* special MSDOS swapping library */
  19. #endif
  20.  
  21. #ifdef HAVE_FCNTL_H
  22. # include <fcntl.h>
  23. #endif
  24.  
  25. #if defined(UNIX) || defined(VMS)
  26. static int file_owned __ARGS((char *fname));
  27. #endif
  28. static void mainerr __ARGS((int, char_u *));
  29. static void main_msg __ARGS((char *s));
  30. static void usage __ARGS((void));
  31. static int get_number_arg __ARGS((char_u *p, int *idx, int def));
  32. static void main_start_gui __ARGS((void));
  33. #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
  34. static void check_swap_exists_action __ARGS((void));
  35. #endif
  36. #ifdef FEAT_CLIENTSERVER
  37. static void cmdsrv_main __ARGS((int *argc, char **argv, char_u *serverName_arg, char_u **serverStr));
  38. static char_u *serverMakeName __ARGS((char_u *arg, char *cmd));
  39. #endif
  40.  
  41.  
  42. #ifdef STARTUPTIME
  43. static FILE *time_fd = NULL;
  44. #endif
  45.  
  46. #define FEAT_PRECOMMANDS
  47.  
  48. /*
  49.  * Different types of error messages.
  50.  */
  51. static char *(main_errors[]) =
  52. {
  53.     N_("Unknown option"),
  54. #define ME_UNKNOWN_OPTION    0
  55.     N_("Too many edit arguments"),
  56. #define ME_TOO_MANY_ARGS    1
  57.     N_("Argument missing after"),
  58. #define ME_ARG_MISSING        2
  59.     N_("Garbage after option"),
  60. #define ME_GARBAGE        3
  61.     N_("Too many \"+command\" or \"-c command\" arguments"),
  62. #define ME_EXTRA_CMD        4
  63.     N_("Invalid argument for"),
  64. #define ME_INVALID_ARG        5
  65. };
  66.  
  67. /* Maximum number of commands from + or -c options */
  68. #define MAX_ARG_CMDS 10
  69.  
  70. #ifndef PROTO        /* don't want a prototype for main() */
  71.     int
  72. # ifdef VIMDLL
  73. _export
  74. # endif
  75. # ifdef FEAT_GUI_MSWIN
  76. #  ifdef __BORLANDC__
  77. _cdecl
  78. #  endif
  79. VimMain
  80. # else
  81. main
  82. # endif
  83. (argc, argv)
  84.     int        argc;
  85.     char    **argv;
  86. {
  87.     char_u    *initstr;        /* init string from environment */
  88.     char_u    *term = NULL;        /* specified terminal name */
  89.     char_u    *fname = NULL;        /* file name from command line */
  90.     char_u    *tagname = NULL;    /* tag from -t option */
  91.     char_u    *use_vimrc = NULL;    /* vimrc from -u option */
  92. #ifdef FEAT_QUICKFIX
  93.     char_u    *use_ef = NULL;        /* 'errorfile' from -q option */
  94. #endif
  95. #ifdef FEAT_CRYPT
  96.     int        ask_for_key = FALSE;    /* -x argument */
  97. #endif
  98.     int        n_commands = 0;        /* no. of commands from + or -c */
  99.     char_u    *commands[MAX_ARG_CMDS]; /* commands from + or -c option */
  100. #ifdef FEAT_PRECOMMANDS
  101.     int        p_commands = 0;        /* no. of commands from --cmd */
  102.     char_u    *pre_commands[MAX_ARG_CMDS]; /* commands from --cmd option */
  103. #endif
  104.     int        no_swap_file = FALSE;   /* "-n" option used */
  105.     int        c;
  106.     int        i;
  107.     char_u    *p = NULL;
  108.     int        bin_mode = FALSE;    /* -b option used */
  109. #ifdef FEAT_WINDOWS
  110.     int        window_count = -1;    /* number of windows to use */
  111.     int        arg_idx;        /* index in argument list */
  112.     int        vert_windows = MAYBE;   /* "-O" used instead of "-o" */
  113. #endif
  114.     int        had_minmin = FALSE;    /* found "--" option */
  115.     int        argv_idx;        /* index in argv[n][] */
  116.     int        want_full_screen = TRUE;
  117.     int        want_argument;        /* option with argument */
  118. #define EDIT_NONE   0        /* no edit type yet */
  119. #define EDIT_FILE   1        /* file name argument[s] given, use argument list */
  120. #define EDIT_STDIN  2        /* read file from stdin */
  121. #define EDIT_TAG    3        /* tag name argument given, use tagname */
  122. #define EDIT_QF        4        /* start in quickfix mode */
  123.     int        edit_type = EDIT_NONE;  /* type of editing to do */
  124. #ifdef FEAT_DIFF
  125.     int        diff_mode = FALSE;    /* start with 'diff' set */
  126. #endif
  127.     int        evim_mode = FALSE;    /* started as "evim" */
  128.     int        stdout_isatty;        /* is stdout a terminal? */
  129.     int        input_isatty;        /* is active input a terminal? */
  130. #ifdef MSWIN
  131.     int        full_path = FALSE;
  132. #endif
  133. #ifdef FEAT_CLIENTSERVER
  134.     char_u    *serverStr = NULL;
  135.     char_u    *serverName_arg = NULL;    /* cmdline arg for server name */
  136.     int        serverArg = FALSE;    /* TRUE when argument for a server */
  137.     char_u    *servername = NULL;    /* allocated name for our server */
  138. #endif
  139. #if (!defined(UNIX) && !defined(__EMX__)) || defined(ARCHIE)
  140.     int        literal = FALSE;    /* don't expand file names */
  141. #endif
  142.  
  143.     /*
  144.      * Do any system-specific initialisations.  These can NOT use IObuff or
  145.      * NameBuff.  Thus emsg2() cannot be called!
  146.      */
  147.     mch_early_init();
  148.  
  149. #ifdef FEAT_TCL
  150.     tcl_init(argv[0]);
  151. #endif
  152.  
  153. #ifdef MEM_PROFILE
  154.     atexit(vim_mem_profile_dump);
  155. #endif
  156.  
  157. #ifdef STARTUPTIME
  158.     time_fd = fopen(STARTUPTIME, "a");
  159.     TIME_MSG("--- VIM STARTING ---");
  160. #endif
  161.  
  162. #ifdef __EMX__
  163.     _wildcard(&argc, &argv);
  164. #endif
  165.  
  166. #ifdef FEAT_MBYTE
  167.     (void)mb_init();    /* init mb_bytelen_tab[] to ones */
  168. #endif
  169.  
  170. #ifdef __QNX__
  171.     qnx_init();        /* PhAttach() for clipboard, mouse (and gui) */
  172. #endif
  173.  
  174. #ifdef FEAT_GUI_MAC
  175.     /* Macintosh needs this before any memory is allocated. */
  176.     gui_prepare(&argc, argv);    /* Prepare for possibly starting GUI sometime */
  177.     TIME_MSG("GUI prepared");
  178. #endif
  179.  
  180.     /* Init the table of Normal mode commands. */
  181.     init_normal_cmds();
  182.  
  183. #if defined(HAVE_DATE_TIME) && defined(VMS) && defined(VAXC)
  184.     make_version();
  185. #endif
  186.  
  187.     /*
  188.      * Allocate space for the generic buffers (needed for set_init_1() and
  189.      * EMSG2()).
  190.      */
  191.     if ((IObuff = alloc(IOSIZE)) == NULL
  192.         || (NameBuff = alloc(MAXPATHL)) == NULL)
  193.     mch_exit(0);
  194.  
  195.     TIME_MSG("Allocated generic buffers");
  196.  
  197. #if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
  198.     /*
  199.      * Setup to use the current locale (for ctype() and many other things).
  200.      * NOTE: Translated messages with encodings other than latin1 will not
  201.      * work until set_init_1() has been called!
  202.      */
  203.     setlocale(LC_ALL, "");
  204.  
  205. # ifdef FEAT_GETTEXT
  206.     {
  207.     int    mustfree = FALSE;
  208.  
  209. #ifdef DYNAMIC_GETTEXT
  210.     /* Initialize the gettext library */
  211.     dyn_libintl_init(NULL);
  212. #endif
  213.     /* expand_env() doesn't work yet, because chartab[] is not initialized
  214.      * yet, call vim_getenv() directly */
  215.     p = vim_getenv((char_u *)"VIMRUNTIME", &mustfree);
  216.     if (p != NULL && *p != NUL)
  217.     {
  218.         STRCPY(NameBuff, p);
  219.         STRCAT(NameBuff, "/lang");
  220.         bindtextdomain(VIMPACKAGE, (char *)NameBuff);
  221.     }
  222.     if (mustfree)
  223.         vim_free(p);
  224.     textdomain(VIMPACKAGE);
  225.     }
  226. # endif
  227.     TIME_MSG("locale set");
  228. #endif
  229.  
  230. #ifdef FEAT_GUI
  231.     gui.dofork = TRUE;            /* default is to use fork() */
  232. #endif
  233.  
  234. #if defined(FEAT_XCLIPBOARD) || defined(FEAT_CLIENTSERVER)
  235.     /*
  236.      * Get the name of the display, before gui_prepare() removes it from
  237.      * argv[].  Used for the xterm-clipboard display.
  238.      *
  239.      * Also find the --server... arguments
  240.      */
  241.     for (i = 1; i < argc; i++)
  242.     {
  243.     if (STRCMP(argv[i], "--") == 0)
  244.         break;
  245. # ifdef FEAT_XCLIPBOARD
  246.     else if (STRICMP(argv[i], "-display") == 0
  247. #  ifdef FEAT_GUI_GTK
  248.         || STRICMP(argv[i], "--display") == 0
  249. #  endif
  250.         )
  251.     {
  252.         if (i == argc - 1)
  253.         mainerr_arg_missing((char_u *)argv[i]);
  254.         xterm_display = argv[++i];
  255.     }
  256. # endif
  257. # ifdef FEAT_CLIENTSERVER
  258.     else if (STRICMP(argv[i], "--servername") == 0)
  259.     {
  260.         if (i == argc - 1)
  261.         mainerr_arg_missing((char_u *)argv[i]);
  262.         serverName_arg = (char_u *)argv[++i];
  263.     }
  264.     else if (STRICMP(argv[i], "--serverlist") == 0
  265.          || STRICMP(argv[i], "--remote-send") == 0
  266.          || STRICMP(argv[i], "--remote-expr") == 0
  267.          || STRICMP(argv[i], "--remote") == 0 )
  268.         serverArg = TRUE;
  269.     else if (STRICMP(argv[i], "--remote-wait") == 0)
  270.     {
  271.         serverArg = TRUE;
  272. #ifdef FEAT_GUI
  273.         /* don't fork() when starting the GUI to edit the files ourself */
  274.         gui.dofork = FALSE;
  275. #endif
  276.     }
  277. # endif
  278. # ifdef FEAT_GUI_GTK
  279.     else if (STRICMP(argv[i], "--socketid") == 0)
  280.     {
  281.         int count;
  282.  
  283.         if (i == argc - 1)
  284.         mainerr_arg_missing((char_u *)argv[i]);
  285.         if (STRNICMP(argv[i+1], "0x", 2) == 0)
  286.         count = sscanf(&(argv[i + 1][2]), "%x", >k_socket_id);
  287.         else
  288.         count = sscanf(argv[i+1], "%d", >k_socket_id);
  289.         if (count != 1)
  290.         mainerr(ME_INVALID_ARG, (char_u *)argv[i]);
  291.         i++;
  292.     }
  293. # endif
  294.     }
  295. #endif
  296.  
  297. #ifdef FEAT_SUN_WORKSHOP
  298.     findYourself(argv[0]);
  299. #endif
  300. #if defined(FEAT_GUI) && !defined(FEAT_GUI_MAC)
  301.     gui_prepare(&argc, argv);    /* Prepare for possibly starting GUI sometime */
  302.     TIME_MSG("GUI prepared");
  303. #endif
  304.  
  305. #ifdef FEAT_CLIPBOARD
  306.     clip_init(FALSE);        /* Initialise clipboard stuff */
  307.     TIME_MSG("clipboard setup");
  308. #endif
  309.  
  310.     /*
  311.      * Check if we have an interactive window.
  312.      * On the Amiga: If there is no window, we open one with a newcli command
  313.      * (needed for :! to * work). mch_check_win() will also handle the -d or
  314.      * -dev argument.
  315.      */
  316.     stdout_isatty = (mch_check_win(argc, argv) != FAIL);
  317.     TIME_MSG("window checked");
  318.  
  319.     /*
  320.      * Allocate the first window and buffer. Can't do much without it.
  321.      */
  322.     win_alloc_first();
  323.  
  324.     init_yank();        /* init yank buffers */
  325.  
  326.     /* Init the argument list to empty. */
  327.     alist_init(&global_alist);
  328.  
  329.     /*
  330.      * Set the default values for the options.
  331.      * NOTE: Non-latin1 translated messages are working only after this,
  332.      * because this is where "has_mbyte" will be set, which is used by
  333.      * msg_outtrans_len_attr().
  334.      * First find out the home directory, needed to expand "~" in options.
  335.      */
  336.     init_homedir();        /* find real value of $HOME */
  337.     set_init_1();
  338.     TIME_MSG("inits 1");
  339.  
  340. #ifdef FEAT_EVAL
  341.     set_lang_var();        /* set v:lang and v:ctype */
  342. #endif
  343.  
  344. #ifdef FEAT_CLIENTSERVER
  345.     /*
  346.      * Do the client-server stuff, unless "--servername ''" was used.
  347.      */
  348.     if (serverName_arg == NULL || *serverName_arg != NUL)
  349.     {
  350. # ifdef WIN32
  351.     /* Initialise the client/server messaging infrastructure. */
  352.     serverInitMessaging();
  353. # endif
  354.  
  355.     /*
  356.      * When a command server argument was found, execute it.  This may
  357.      * exit Vim when it was successful.
  358.      */
  359.     if (serverArg)
  360.         cmdsrv_main(&argc, argv, serverName_arg, &serverStr);
  361.  
  362.     /* If we're still running, get the name to register ourselves.
  363.      * On Win32 can register right now, for X11 need to setup the
  364.      * clipboard first, it's further down. */
  365.     servername = serverMakeName(serverName_arg, argv[0]);
  366. # ifdef WIN32
  367.     if (servername != NULL)
  368.     {
  369.         serverSetName(servername);
  370.         vim_free(servername);
  371.     }
  372. # endif
  373.     }
  374. #endif
  375.  
  376.     /*
  377.      * Check for: [r][e][g][vi|vim|view][diff][ex[im]]
  378.      * If the executable name starts with "r" we disable shell commands.
  379.      * If the next character is "e" we run in Easy mode.
  380.      * If the next character is "g" we run the GUI version.
  381.      * If the next characters are "view" we start in readonly mode.
  382.      * If the next characters are "diff" or "vimdiff" we start in diff mode.
  383.      * If the next characters are "ex" we start in Ex mode.  If it's followed
  384.      * by "im" use improved Ex mode.
  385.      */
  386.     initstr = gettail((char_u *)argv[0]);
  387.  
  388. #ifdef FEAT_EVAL
  389.     set_vim_var_string(VV_PROGNAME, initstr, -1);
  390. #endif
  391.  
  392.     /* TODO: On MacOS X default to gui if argv[0] ends in:
  393.      *       /vim.app/Contents/MacOS/Vim */
  394.  
  395.     if (TO_LOWER(initstr[0]) == 'r')
  396.     {
  397.     restricted = TRUE;
  398.     ++initstr;
  399.     }
  400.  
  401.     /* Avoid using evim mode for "editor". */
  402.     if (TO_LOWER(initstr[0]) == 'e'
  403.         && (TO_LOWER(initstr[1]) == 'v' || TO_LOWER(initstr[1]) == 'g'))
  404.     {
  405. #ifdef FEAT_GUI
  406.     gui.starting = TRUE;
  407. #endif
  408.     evim_mode = TRUE;
  409.     ++initstr;
  410.     }
  411.  
  412.     if (TO_LOWER(initstr[0]) == 'g')
  413.     {
  414.     main_start_gui();
  415. #ifdef FEAT_GUI
  416.     ++initstr;
  417. #endif
  418.     }
  419.  
  420.     if (STRNICMP(initstr, "view", 4) == 0)
  421.     {
  422.     readonlymode = TRUE;
  423.     curbuf->b_p_ro = TRUE;
  424.     p_uc = 10000;            /* don't update very often */
  425.     initstr += 4;
  426.     }
  427.     else if (STRNICMP(initstr, "vim", 3) == 0)
  428.     initstr += 3;
  429.  
  430.     /* Catch "[r][g]vimdiff" and "[r][g]viewdiff". */
  431.     if (STRICMP(initstr, "diff") == 0)
  432.     {
  433. #ifdef FEAT_DIFF
  434.     diff_mode = TRUE;
  435. #else
  436.     mch_errmsg(_("This Vim was not compiled with the diff feature."));
  437.     mch_errmsg("\n");
  438.     mch_exit(2);
  439. #endif
  440.     }
  441.  
  442.     if (STRNICMP(initstr, "ex", 2) == 0)
  443.     {
  444.     if (STRNICMP(initstr + 2, "im", 2) == 0)
  445.         exmode_active = EXMODE_VIM;
  446.     else
  447.         exmode_active = EXMODE_NORMAL;
  448.     change_compatible(TRUE);    /* set 'compatible' */
  449.     }
  450.  
  451.     initstr = gettail((char_u *)argv[0]);
  452.     ++argv;
  453.     --argc;
  454.  
  455.     /*
  456.      * Process the command line arguments.
  457.      */
  458.     argv_idx = 1;        /* active option letter is argv[0][argv_idx] */
  459.     while (argc > 0)
  460.     {
  461.     /*
  462.      * "+" or "+{number}" or "+/{pat}" or "+{command}" argument.
  463.      */
  464.     if (argv[0][0] == '+' && !had_minmin)
  465.     {
  466.         if (n_commands >= MAX_ARG_CMDS)
  467.         mainerr(ME_EXTRA_CMD, NULL);
  468.         argv_idx = -1;        /* skip to next argument */
  469.         if (argv[0][1] == NUL)
  470.         commands[n_commands++] = (char_u *)"$";
  471.         else
  472.         commands[n_commands++] = (char_u *)&(argv[0][1]);
  473.     }
  474.  
  475.     /*
  476.      * Optional argument.
  477.      */
  478.     else if (argv[0][0] == '-' && !had_minmin)
  479.     {
  480.         want_argument = FALSE;
  481.         c = argv[0][argv_idx++];
  482. #ifdef VMS
  483.         /*
  484.          * VMS only uses upper case command lines.  Interpret "-X" as "-x"
  485.          * and "-/X" as "-X".
  486.          */
  487.         if (c == '/')
  488.         {
  489.         c = argv[0][argv_idx++];
  490.         c = TO_UPPER(c);
  491.         }
  492.         else
  493.         c = TO_LOWER(c);
  494. #endif
  495.         switch (c)
  496.         {
  497.         case NUL:        /* "vim -"  read from stdin */
  498.                 /* "ex -" silent mode */
  499.         if (exmode_active)
  500.             silent_mode = TRUE;
  501.         else
  502.         {
  503.             if (edit_type != EDIT_NONE)
  504.             mainerr(ME_TOO_MANY_ARGS, (char_u *)argv[0]);
  505.             edit_type = EDIT_STDIN;
  506.             read_cmd_fd = 2;    /* read from stderr instead of stdin */
  507.         }
  508.         argv_idx = -1;        /* skip to next argument */
  509.         break;
  510.  
  511.         case '-':        /* "--" don't take any more options */
  512.                 /* "--help" give help message */
  513.                 /* "--version" give version message */
  514.                 /* "--literal" take files literally */
  515.                 /* "--noplugin[s]" skip plugins */
  516.                 /* "--cmd <cmd>" execute cmd before vimrc */
  517.         if (STRICMP(argv[0] + argv_idx, "help") == 0)
  518.             usage();
  519.         else if (STRICMP(argv[0] + argv_idx, "version") == 0)
  520.         {
  521.             Columns = 80;    /* need to init Columns */
  522.             list_version();
  523.             mch_exit(1);
  524.         }
  525.         else if (STRNICMP(argv[0] + argv_idx, "literal", 7) == 0)
  526.         {
  527. #if (!defined(UNIX) && !defined(__EMX__)) || defined(ARCHIE)
  528.             literal = TRUE;
  529. #endif
  530.         }
  531.         else if (STRNICMP(argv[0] + argv_idx, "noplugin", 8) == 0)
  532.             p_lpl = FALSE;
  533. #ifdef FEAT_PRECOMMANDS
  534.         else if (STRNICMP(argv[0] + argv_idx, "cmd", 3) == 0)
  535.         {
  536.             want_argument = TRUE;
  537.             argv_idx += 3;
  538.         }
  539. #endif
  540. #ifdef FEAT_CLIENTSERVER
  541.         else if (STRNICMP(argv[0] + argv_idx, "serverlist", 10) == 0)
  542.             ; /* already processed -- no arg */
  543.         else if (STRNICMP(argv[0] + argv_idx, "servername", 10) == 0
  544.                || STRNICMP(argv[0] + argv_idx, "serversend", 10) == 0)
  545.         {
  546.             /* already processed -- snatch the following arg */
  547.             if (argc > 1)
  548.             {
  549.             --argc;
  550.             ++argv;
  551.             }
  552.         }
  553. #endif
  554. #ifdef FEAT_GUI_GTK
  555.         else if (STRNICMP(argv[0] + argv_idx, "socketid", 8) == 0)
  556.         {
  557.             /* already processed -- snatch the following arg */
  558.             if (argc > 1)
  559.             {
  560.             --argc;
  561.             ++argv;
  562.             }
  563.         }
  564. #endif
  565.         else
  566.         {
  567.             if (argv[0][argv_idx])
  568.             mainerr(ME_UNKNOWN_OPTION, (char_u *)argv[0]);
  569.             had_minmin = TRUE;
  570.         }
  571.         if (!want_argument)
  572.             argv_idx = -1;    /* skip to next argument */
  573.         break;
  574.  
  575.         case 'b':        /* "-b" binary mode */
  576.         bin_mode = TRUE;    /* postpone to after reading .exrc files */
  577.         break;
  578.  
  579.         case 'C':        /* "-C"  Compatible */
  580.         change_compatible(TRUE);
  581.         break;
  582.  
  583.         case 'e':        /* "-e" Ex mode */
  584.         exmode_active = EXMODE_NORMAL;
  585.         break;
  586.  
  587.         case 'E':        /* "-E" Improved Ex mode */
  588.         exmode_active = EXMODE_VIM;
  589.         break;
  590.  
  591.         case 'f':        /* "-f"  GUI: run in foreground.  Amiga: open
  592.                 window directly, not with newcli */
  593. #ifdef FEAT_GUI
  594.         gui.dofork = FALSE;    /* don't fork() when starting GUI */
  595. #endif
  596.         break;
  597.  
  598.         case 'g':        /* "-g" start GUI */
  599.         main_start_gui();
  600.         break;
  601.  
  602.         case 'F':        /* "-F" start in Farsi mode: rl + fkmap set */
  603. #ifdef FEAT_FKMAP
  604.         curwin->w_p_rl = p_fkmap = TRUE;
  605. #else
  606.         mch_errmsg(_(e_nofarsi));
  607.         mch_exit(2);
  608. #endif
  609.         break;
  610.  
  611.         case 'h':        /* "-h" give help message */
  612.         usage();
  613.         break;
  614.  
  615.         case 'H':        /* "-H" start in Hebrew mode: rl + hkmap set */
  616. #ifdef FEAT_RIGHTLEFT
  617.         curwin->w_p_rl = p_hkmap = TRUE;
  618. #else
  619.         mch_errmsg(_(e_nohebrew));
  620.         mch_exit(2);
  621. #endif
  622.         break;
  623.  
  624.         case 'l':        /* "-l" lisp mode, 'lisp' and 'showmatch' on */
  625. #ifdef FEAT_LISP
  626.         curbuf->b_p_lisp = TRUE;
  627.         p_sm = TRUE;
  628. #endif
  629.         break;
  630.  
  631. #ifdef TARGET_API_MAC_OSX
  632.         /* For some reason on MacOS X, an argument like:
  633.            -psn_0_10223617 is passed in when invoke from Finder
  634.            or with the 'open' command */
  635.         case 'p':
  636.         mch_errmsg("What does this mean: ");
  637.         mch_errmsg(argv[0]);
  638.         mch_errmsg("\n");
  639.         argv_idx = -1; /* bypass full -psn */
  640.         break;
  641. #endif
  642.         case 'M':        /* "-M"  no changes or writing of files */
  643.         reset_modifiable();
  644.         /* FALLTRHOUGH */
  645.  
  646.         case 'm':        /* "-m"  no writing of files */
  647.         p_write = FALSE;
  648.         break;
  649.  
  650.         case 'y':        /* "-y"  easy mode */
  651. #ifdef FEAT_GUI
  652.         gui.starting = TRUE;    /* start GUI a bit later */
  653. #endif
  654.         evim_mode = TRUE;
  655.         break;
  656.  
  657.         case 'N':        /* "-N"  Nocompatible */
  658.         change_compatible(FALSE);
  659.         break;
  660.  
  661.         case 'n':        /* "-n" no swap file */
  662.         no_swap_file = TRUE;
  663.         break;
  664.  
  665.         case 'o':        /* "-o[N]" open N horizontal split windows */
  666. #ifdef FEAT_WINDOWS
  667.         /* default is 0: open window for each file */
  668.         window_count = get_number_arg((char_u *)argv[0], &argv_idx, 0);
  669.         vert_windows = FALSE;
  670. #endif
  671.         break;
  672.  
  673.         case 'O':    /* "-O[N]" open N vertical split windows */
  674. #if defined(FEAT_VERTSPLIT) && defined(FEAT_WINDOWS)
  675.         /* default is 0: open window for each file */
  676.         window_count = get_number_arg((char_u *)argv[0], &argv_idx, 0);
  677.         vert_windows = TRUE;
  678. #endif
  679.         break;
  680.  
  681. #ifdef FEAT_QUICKFIX
  682.         case 'q':        /* "-q" QuickFix mode */
  683.         if (edit_type != EDIT_NONE)
  684.             mainerr(ME_TOO_MANY_ARGS, (char_u *)argv[0]);
  685.         edit_type = EDIT_QF;
  686.         if (argv[0][argv_idx])        /* "-q{errorfile}" */
  687.         {
  688.             use_ef = (char_u *)argv[0] + argv_idx;
  689.             argv_idx = -1;
  690.         }
  691.         else if (argc > 1)        /* "-q {errorfile}" */
  692.             want_argument = TRUE;
  693.         break;
  694. #endif
  695.  
  696.         case 'R':        /* "-R" readonly mode */
  697.         readonlymode = TRUE;
  698.         curbuf->b_p_ro = TRUE;
  699.         p_uc = 10000;            /* don't update very often */
  700.         break;
  701.  
  702.         case 'r':        /* "-r" recovery mode */
  703.         case 'L':        /* "-L" recovery mode */
  704.         recoverymode = 1;
  705.         break;
  706.  
  707.         case 's':
  708.         if (exmode_active)    /* "-s" silent (batch) mode */
  709.             silent_mode = TRUE;
  710.         else        /* "-s {scriptin}" read from script file */
  711.             want_argument = TRUE;
  712.         break;
  713.  
  714.         case 't':        /* "-t {tag}" or "-t{tag}" jump to tag */
  715.         if (edit_type != EDIT_NONE)
  716.             mainerr(ME_TOO_MANY_ARGS, (char_u *)argv[0]);
  717.         edit_type = EDIT_TAG;
  718.         if (argv[0][argv_idx])        /* "-t{tag}" */
  719.         {
  720.             tagname = (char_u *)argv[0] + argv_idx;
  721.             argv_idx = -1;
  722.         }
  723.         else                /* "-t {tag}" */
  724.             want_argument = TRUE;
  725.         break;
  726.  
  727. #ifdef FEAT_EVAL
  728.         case 'D':        /* "-D"        Debugging */
  729.         debug_break_level = 9999;
  730.         break;
  731. #endif
  732. #ifdef FEAT_DIFF
  733.         case 'd':        /* "-d"        'diff' */
  734. # ifdef AMIGA
  735.         /* check for "-dev {device}" */
  736.         if (argv[0][argv_idx] == 'e' && argv[0][argv_idx + 1] == 'v')
  737.             want_argument = TRUE;
  738.         else
  739. # endif
  740.             diff_mode = TRUE;
  741.         break;
  742. #endif
  743.         case 'V':        /* "-V{N}"    Verbose level */
  744.         /* default is 10: a little bit verbose */
  745.         p_verbose = get_number_arg((char_u *)argv[0], &argv_idx, 10);
  746.         break;
  747.  
  748.         case 'v':        /* "-v"  Vi-mode (as if called "vi") */
  749.         exmode_active = 0;
  750. #ifdef FEAT_GUI
  751.         gui.starting = FALSE;    /* don't start GUI */
  752. #endif
  753.         break;
  754.  
  755.         case 'w':        /* "-w{number}"    set window height */
  756.                 /* "-w {scriptout}"    write to script */
  757.         if (isdigit(((char_u *)argv[0])[argv_idx]))
  758.         {
  759.             argv_idx = -1;
  760.             break;            /* not implemented, ignored */
  761.         }
  762.         want_argument = TRUE;
  763.         break;
  764.  
  765. #ifdef FEAT_CRYPT
  766.         case 'x':        /* "-x"  encrypted reading/writing of files */
  767.         ask_for_key = TRUE;
  768.         break;
  769. #endif
  770.  
  771.         case 'X':        /* "-X"  don't connect to X server */
  772. #if (defined(UNIX) || defined(VMS)) && defined(FEAT_X11)
  773.         x_no_connect = TRUE;
  774. #endif
  775.         break;
  776.  
  777.         case 'Z':        /* "-Z"  restricted mode */
  778.         restricted = TRUE;
  779.         break;
  780.  
  781.         case 'c':        /* "-c {command}" execute command */
  782.         case 'S':        /* "-S {file}" execute Vim script */
  783.         case 'i':        /* "-i {viminfo}" use for viminfo */
  784. #ifndef FEAT_DIFF
  785.         case 'd':        /* "-d {device}" device (for Amiga) */
  786. #endif
  787.         case 'T':        /* "-T {terminal}" terminal name */
  788.         case 'u':        /* "-u {vimrc}" vim inits file */
  789.         case 'U':        /* "-U {gvimrc}" gvim inits file */
  790.         case 'W':        /* "-W {scriptout}" overwrite */
  791.         want_argument = TRUE;
  792.         break;
  793.  
  794.         default:
  795.         mainerr(ME_UNKNOWN_OPTION, (char_u *)argv[0]);
  796.         }
  797.  
  798.         /*
  799.          * Handle options with argument.
  800.          */
  801.         if (want_argument)
  802.         {
  803.         /*
  804.          * Check for garbage immediately after the option letter.
  805.          */
  806.         if (argv[0][argv_idx] != NUL)
  807.             mainerr(ME_GARBAGE, (char_u *)argv[0]);
  808.  
  809.         --argc;
  810.         if (argc < 1)
  811.             mainerr_arg_missing((char_u *)argv[0]);
  812.         ++argv;
  813.         argv_idx = -1;
  814.  
  815.         switch (c)
  816.         {
  817.         case 'c':    /* "-c {command}" execute command */
  818.         case 'S':    /* "-S {file}" execute Vim script */
  819.             if (n_commands >= MAX_ARG_CMDS)
  820.             mainerr(ME_EXTRA_CMD, NULL);
  821.             if (c == 'S')
  822.             {
  823.             p = alloc((unsigned)(STRLEN(argv[0]) + 4));
  824.             if (p == NULL)
  825.                 mch_exit(2);
  826.             sprintf((char *)p, "so %s", argv[0]);
  827.             commands[n_commands++] = p;
  828.             }
  829.             else
  830.             commands[n_commands++] = (char_u *)argv[0];
  831.             break;
  832.  
  833. #ifdef FEAT_PRECOMMANDS
  834.         case '-':    /* "--cmd {command}" execute command */
  835.             if (n_commands >= MAX_ARG_CMDS)
  836.             mainerr(ME_EXTRA_CMD, NULL);
  837.             pre_commands[p_commands++] = (char_u *)argv[0];
  838.             break;
  839. #endif
  840.  
  841.         /*    case 'd':   -d {device} is handled in mch_check_win() for the
  842.          *            Amiga */
  843.  
  844. #ifdef FEAT_QUICKFIX
  845.         case 'q':    /* "-q {errorfile}" QuickFix mode */
  846.             use_ef = (char_u *)argv[0];
  847.             break;
  848. #endif
  849.  
  850.         case 'i':    /* "-i {viminfo}" use for viminfo */
  851.             use_viminfo = (char_u *)argv[0];
  852.             break;
  853.  
  854.         case 's':    /* "-s {scriptin}" read from script file */
  855.             if (scriptin[0] != NULL)
  856.             {
  857. scripterror:
  858.             mch_errmsg(_("Attempt to open script file again: \""));
  859.             mch_errmsg(argv[-1]);
  860.             mch_errmsg(" ");
  861.             mch_errmsg(argv[0]);
  862.             mch_errmsg(_("\"\n"));
  863.             mch_exit(2);
  864.             }
  865.             if ((scriptin[0] = mch_fopen(argv[0], READBIN)) == NULL)
  866.             {
  867.             mch_errmsg(_("Cannot open for reading: \""));
  868.             mch_errmsg(argv[0]);
  869.             mch_errmsg(_("\"\n"));
  870.             mch_exit(2);
  871.             }
  872.             if (save_typebuf() == FAIL)
  873.             mch_exit(2);    /* out of memory */
  874.             break;
  875.  
  876.         case 't':    /* "-t {tag}" */
  877.             tagname = (char_u *)argv[0];
  878.             break;
  879.  
  880.         case 'T':    /* "-T {terminal}" terminal name */
  881.             /*
  882.              * The -T term option is always available and when
  883.              * HAVE_TERMLIB is supported it overrides the environment
  884.              * variable TERM.
  885.              */
  886. #ifdef FEAT_GUI
  887.             if (term_is_gui((char_u *)argv[0]))
  888.             gui.starting = TRUE;    /* start GUI a bit later */
  889.             else
  890. #endif
  891.             term = (char_u *)argv[0];
  892.             break;
  893.  
  894.         case 'u':    /* "-u {vimrc}" vim inits file */
  895.             use_vimrc = (char_u *)argv[0];
  896.             break;
  897.  
  898.         case 'U':    /* "-U {gvimrc}" gvim inits file */
  899. #ifdef FEAT_GUI
  900.             use_gvimrc = (char_u *)argv[0];
  901. #endif
  902.             break;
  903.  
  904.         case 'w':    /* "-w {scriptout}" append to script file */
  905.         case 'W':    /* "-W {scriptout}" overwrite script file */
  906.             if (scriptout != NULL)
  907.             goto scripterror;
  908.             if ((scriptout = mch_fopen(argv[0],
  909.                     c == 'w' ? APPENDBIN : WRITEBIN)) == NULL)
  910.             {
  911.             mch_errmsg(_("Cannot open for script output: \""));
  912.             mch_errmsg(argv[0]);
  913.             mch_errmsg(_("\"\n"));
  914.             mch_exit(2);
  915.             }
  916.             break;
  917.         }
  918.         }
  919.     }
  920.  
  921.     /*
  922.      * File name argument.
  923.      */
  924.     else
  925.     {
  926.         argv_idx = -1;        /* skip to next argument */
  927.  
  928.         /* Check for only one type of editing. */
  929.         if (edit_type != EDIT_NONE && edit_type != EDIT_FILE)
  930.         mainerr(ME_TOO_MANY_ARGS, (char_u *)argv[0]);
  931.         edit_type = EDIT_FILE;
  932.  
  933. #ifdef MSWIN
  934.         /* Remember if the argument was a full path before changing
  935.          * slashes to backslashes. */
  936.         if (argv[0][0] != NUL && argv[0][1] == ':' && argv[0][2] == '\\')
  937.         full_path = TRUE;
  938. #endif
  939.  
  940.         /* Add the file to the global argument list. */
  941.         if (ga_grow(&global_alist.al_ga, 1) == FAIL
  942.             || (p = vim_strsave((char_u *)argv[0])) == NULL)
  943.         mch_exit(2);
  944. #ifdef FEAT_DIFF
  945.         if (diff_mode && mch_isdir(p) && GARGCOUNT > 0
  946.                       && !mch_isdir(alist_name(&GARGLIST[0])))
  947.         {
  948.         char_u        *r;
  949.  
  950.         r = concat_fnames(p, gettail(alist_name(&GARGLIST[0])), TRUE);
  951.         if (r != NULL)
  952.         {
  953.             vim_free(p);
  954.             p = r;
  955.         }
  956.         }
  957. #endif
  958.         alist_add(&global_alist, p,
  959. #if (!defined(UNIX) && !defined(__EMX__)) || defined(ARCHIE)
  960.             literal ? 2 : 0    /* add buffer number after expanding */
  961. #else
  962.             2        /* add buffer number now and use curbuf */
  963. #endif
  964.             );
  965.     }
  966.  
  967.     /*
  968.      * If there are no more letters after the current "-", go to next
  969.      * argument.  argv_idx is set to -1 when the current argument is to be
  970.      * skipped.
  971.      */
  972.     if (argv_idx <= 0 || argv[0][argv_idx] == NUL)
  973.     {
  974.         --argc;
  975.         ++argv;
  976.         argv_idx = 1;
  977.     }
  978.     }
  979.     TIME_MSG("parsing arguments");
  980.  
  981.     /*
  982.      * On some systems, when we compile with the GUI, we always use it.  On Mac
  983.      * there is no terminal version, and on Windows we can't figure out how to
  984.      * fork one off with :gui.
  985.      */
  986. #ifdef ALWAYS_USE_GUI
  987.     gui.starting = TRUE;
  988. #else
  989. # if defined(FEAT_GUI_X11) || defined(FEAT_GUI_GTK)
  990.     /*
  991.      * Check if the GUI can be started.  Reset gui.starting if not.
  992.      * Don't know about other systems, stay on the safe side and don't check.
  993.      */
  994.     if (gui.starting && gui_init_check() == FAIL)
  995.     gui.starting = FALSE;
  996. # endif
  997. #endif
  998.  
  999.     /* "-b" argument used.  Check before expanding file names, because for
  1000.      * Win32 this makes us edit a shortcut file itself, instead of the file it
  1001.      * links to. */
  1002.     if (bin_mode)
  1003.     {
  1004.     set_options_bin(curbuf->b_p_bin, 1, 0);
  1005.     curbuf->b_p_bin = 1;        /* binary file I/O */
  1006.     }
  1007.  
  1008.     if (GARGCOUNT > 0)
  1009.     {
  1010. #if (!defined(UNIX) && !defined(__EMX__)) || defined(ARCHIE)
  1011.     /*
  1012.      * Expand wildcards in file names.
  1013.      */
  1014.     if (!literal)
  1015.         alist_expand();
  1016. #endif
  1017.     fname = alist_name(&GARGLIST[0]);
  1018.     }
  1019.     if (GARGCOUNT > 1)
  1020.     printf(_("%d files to edit\n"), GARGCOUNT);
  1021. #ifdef MSWIN
  1022.     else if (GARGCOUNT == 1 && full_path)
  1023.     {
  1024.     /*
  1025.      * If there is one filename, fully qualified, we have very probably
  1026.      * been invoked from explorer, so change to the file's directory.
  1027.      * Hint: to avoid this when typing a command use a forward slash.
  1028.      * If the cd fails, it doesn't matter.
  1029.      */
  1030.     (void)vim_chdirfile(fname);
  1031.     }
  1032. #endif
  1033.     TIME_MSG("expanding arguments");
  1034.  
  1035. #ifdef FEAT_DIFF
  1036.     if (diff_mode)
  1037.     {
  1038.     if (window_count == -1)
  1039.         window_count = 0;        /* open up to 3 files in a window */
  1040.     if (vert_windows == MAYBE)
  1041.         vert_windows = TRUE;    /* use vertical split */
  1042.     }
  1043. #endif
  1044.  
  1045.     ++RedrawingDisabled;
  1046.  
  1047.     /*
  1048.      * When listing swap file names, don't do cursor positioning et. al.
  1049.      */
  1050.     if (recoverymode && fname == NULL)
  1051.     want_full_screen = FALSE;
  1052.  
  1053.     /*
  1054.      * When certain to start the GUI, don't check capabilities of terminal.
  1055.      * For GTK we can't be sure, but when started from the desktop it doesn't
  1056.      * make sense to try using a terminal.
  1057.      */
  1058. #if defined(ALWAYS_USE_GUI) || defined(FEAT_GUI_X11) || defined(FEAT_GUI_GTK)
  1059.     if (gui.starting
  1060. # ifdef FEAT_GUI_GTK
  1061.         && !isatty(2)
  1062. # endif
  1063.         )
  1064.     want_full_screen = FALSE;
  1065. #endif
  1066.  
  1067.     /*
  1068.      * mch_init() sets up the terminal (window) for use.  This must be
  1069.      * done after resetting full_screen, otherwise it may move the cursor
  1070.      * (MSDOS).
  1071.      * Note that we may use mch_exit() before mch_init()!
  1072.      */
  1073.     mch_init();
  1074.     TIME_MSG("shell init");
  1075.  
  1076.     /*
  1077.      * Print a warning if stdout is not a terminal.
  1078.      * When starting in Ex mode and commands come from a file, set Silent mode.
  1079.      */
  1080.     input_isatty = mch_input_isatty();
  1081.     if (exmode_active)
  1082.     {
  1083.     if (!input_isatty)
  1084.         silent_mode = TRUE;
  1085.     }
  1086.     else if (want_full_screen && (!stdout_isatty || !input_isatty)
  1087. #ifdef FEAT_GUI
  1088.         /* don't want the delay when started from the desktop */
  1089.         && !gui.starting
  1090. #endif
  1091.         )
  1092.     {
  1093.     if (!stdout_isatty)
  1094.         mch_errmsg(_("Vim: Warning: Output is not to a terminal\n"));
  1095.     if (!input_isatty)
  1096.         mch_errmsg(_("Vim: Warning: Input is not from a terminal\n"));
  1097.     out_flush();
  1098.     ui_delay(2000L, TRUE);
  1099.     TIME_MSG("Warning delay");
  1100.     }
  1101.  
  1102.     if (want_full_screen)
  1103.     {
  1104.     termcapinit(term);    /* set terminal name and get terminal
  1105.                    capabilities (will set full_screen) */
  1106.     screen_start();        /* don't know where cursor is now */
  1107.     TIME_MSG("Termcap init");
  1108.     }
  1109.  
  1110.     /*
  1111.      * Set the default values for the options that use Rows and Columns.
  1112.      */
  1113.     ui_get_shellsize();        /* inits Rows and Columns */
  1114.     firstwin->w_height = Rows - p_ch;
  1115.     topframe->fr_height = Rows - p_ch;
  1116. #ifdef FEAT_VERTSPLIT
  1117.     firstwin->w_width = Columns;
  1118.     topframe->fr_width = Columns;
  1119. #endif
  1120. #ifdef FEAT_DIFF
  1121.     /* Set the 'diff' option now, so that it can be checked for in a .vimrc
  1122.      * file.  There is no buffer yet though. */
  1123.     if (diff_mode)
  1124.     {
  1125.     diff_win_options(firstwin, FALSE);
  1126.     p_sbo = (char_u *)"ver,hor,jump";
  1127.     }
  1128. #endif
  1129.  
  1130.     cmdline_row = Rows - p_ch;
  1131.     msg_row = cmdline_row;
  1132.     screenalloc(FALSE);        /* allocate screen buffers */
  1133.     set_init_2();
  1134.     TIME_MSG("inits 2");
  1135.  
  1136. #if 0    /* disabled, don't know why it's needed */
  1137.     /*
  1138.      * Don't call msg_start() if the GUI is expected to start, it switches the
  1139.      * cursor off.  Only need to avoid it when want_full_screen could not have
  1140.      * been reset above.
  1141.      * Also don't do it when reading from stdin (the program writing to the
  1142.      * pipe might use the cursor).
  1143.      */
  1144.     if (full_screen && edit_type != EDIT_STDIN
  1145. #if defined(FEAT_GUI) && !defined(ALWAYS_USE_GUI) && !defined(FEAT_GUI_X11)
  1146.         && !gui.starting
  1147. #endif
  1148.        )
  1149.     msg_start();        /* in case a mapping or error message is printed */
  1150. #endif
  1151.     msg_scroll = TRUE;
  1152.     no_wait_return = TRUE;
  1153.  
  1154.     init_mappings();        /* set up initial mappings */
  1155.  
  1156.     init_highlight(TRUE, FALSE); /* set the default highlight groups */
  1157.     TIME_MSG("init highlight");
  1158. #ifdef CURSOR_SHAPE
  1159.     parse_shape_opt(SHAPE_CURSOR); /* set cursor shapes from 'guicursor' */
  1160. #endif
  1161. #ifdef FEAT_MOUSESHAPE
  1162.     parse_shape_opt(SHAPE_MOUSE);  /* set mouse shapes from 'mouseshape' */
  1163. #endif
  1164. #ifdef FEAT_PRINTER
  1165.     parse_list_options(p_popt, printer_opts, OPT_PRINT_NUM_OPTIONS);
  1166. #endif
  1167. #ifdef FEAT_PRECOMMANDS
  1168.     if (p_commands > 0)
  1169.     {
  1170.     curwin->w_cursor.lnum = 0; /* just in case.. */
  1171.     sourcing_name = (char_u *)_("pre-vimrc command line");
  1172.     for (i = 0; i < p_commands; ++i)
  1173.         do_cmdline_cmd(pre_commands[i]);
  1174.     sourcing_name = NULL;
  1175.     }
  1176. #endif
  1177.  
  1178.     /*
  1179.      * For "evim" source evim.vim first of all, so that the user can overrule
  1180.      * any things he doesn't like.
  1181.      */
  1182.     if (evim_mode)
  1183.     {
  1184.     (void)do_source((char_u *)EVIM_FILE, FALSE, FALSE);
  1185.     TIME_MSG("source evim file");
  1186.     }
  1187.  
  1188.     /*
  1189.      * If -u option given, use only the initializations from that file and
  1190.      * nothing else.
  1191.      */
  1192.     if (use_vimrc != NULL)
  1193.     {
  1194.     if (STRCMP(use_vimrc, "NONE") == 0 || STRCMP(use_vimrc, "NORC") == 0)
  1195.     {
  1196. #ifdef FEAT_GUI
  1197.         if (use_gvimrc == NULL)        /* don't load gvimrc either */
  1198.         use_gvimrc = use_vimrc;
  1199. #endif
  1200.         if (use_vimrc[2] == 'N')
  1201.         p_lpl = FALSE;            /* don't load plugins either */
  1202.     }
  1203.     else
  1204.     {
  1205.         if (do_source(use_vimrc, FALSE, FALSE) != OK)
  1206.         EMSG2(_("E282: Cannot read from \"%s\""), use_vimrc);
  1207.     }
  1208.     }
  1209.     else if (!silent_mode)
  1210.     {
  1211. #ifdef AMIGA
  1212.     struct Process    *proc = (struct Process *)FindTask(0L);
  1213.     APTR        save_winptr = proc->pr_WindowPtr;
  1214.  
  1215.     /* Avoid a requester here for a volume that doesn't exist. */
  1216.     proc->pr_WindowPtr = (APTR)-1L;
  1217. #endif
  1218.  
  1219.     /*
  1220.      * Get system wide defaults, if the file name is defined.
  1221.      */
  1222. #ifdef SYS_VIMRC_FILE
  1223.     (void)do_source((char_u *)SYS_VIMRC_FILE, FALSE, FALSE);
  1224. #endif
  1225.  
  1226.     /*
  1227.      * Try to read initialization commands from the following places:
  1228.      * - environment variable VIMINIT
  1229.      * - user vimrc file (s:.vimrc for Amiga, ~/.vimrc otherwise)
  1230.      * - second user vimrc file ($VIM/.vimrc for Dos)
  1231.      * - environment variable EXINIT
  1232.      * - user exrc file (s:.exrc for Amiga, ~/.exrc otherwise)
  1233.      * - second user exrc file ($VIM/.exrc for Dos)
  1234.      * The first that exists is used, the rest is ignored.
  1235.      */
  1236.     if (process_env((char_u *)"VIMINIT", TRUE) != OK)
  1237.     {
  1238.         if (do_source((char_u *)USR_VIMRC_FILE, TRUE, TRUE) == FAIL
  1239. #ifdef USR_VIMRC_FILE2
  1240.         && do_source((char_u *)USR_VIMRC_FILE2, TRUE, TRUE) == FAIL
  1241. #endif
  1242. #ifdef USR_VIMRC_FILE3
  1243.         && do_source((char_u *)USR_VIMRC_FILE3, TRUE, TRUE) == FAIL
  1244. #endif
  1245.         && process_env((char_u *)"EXINIT", FALSE) == FAIL
  1246.         && do_source((char_u *)USR_EXRC_FILE, FALSE, FALSE) == FAIL)
  1247.         {
  1248. #ifdef USR_EXRC_FILE2
  1249.         (void)do_source((char_u *)USR_EXRC_FILE2, FALSE, FALSE);
  1250. #endif
  1251.         }
  1252.     }
  1253.  
  1254.     /*
  1255.      * Read initialization commands from ".vimrc" or ".exrc" in current
  1256.      * directory.  This is only done if the 'exrc' option is set.
  1257.      * Because of security reasons we disallow shell and write commands
  1258.      * now, except for unix if the file is owned by the user or 'secure'
  1259.      * option has been reset in environmet of global ".exrc" or ".vimrc".
  1260.      * Only do this if VIMRC_FILE is not the same as USR_VIMRC_FILE or
  1261.      * SYS_VIMRC_FILE.
  1262.      */
  1263.     if (p_exrc)
  1264.     {
  1265. #if defined(UNIX) || defined(VMS)
  1266.         /* If ".vimrc" file is not owned by user, set 'secure' mode. */
  1267.         if (!file_owned(VIMRC_FILE))
  1268. #endif
  1269.         secure = p_secure;
  1270.  
  1271.         i = FAIL;
  1272.         if (fullpathcmp((char_u *)USR_VIMRC_FILE,
  1273.                       (char_u *)VIMRC_FILE, FALSE) != FPC_SAME
  1274. #ifdef USR_VIMRC_FILE2
  1275.             && fullpathcmp((char_u *)USR_VIMRC_FILE2,
  1276.                       (char_u *)VIMRC_FILE, FALSE) != FPC_SAME
  1277. #endif
  1278. #ifdef USR_VIMRC_FILE3
  1279.             && fullpathcmp((char_u *)USR_VIMRC_FILE3,
  1280.                       (char_u *)VIMRC_FILE, FALSE) != FPC_SAME
  1281. #endif
  1282. #ifdef SYS_VIMRC_FILE
  1283.             && fullpathcmp((char_u *)SYS_VIMRC_FILE,
  1284.                       (char_u *)VIMRC_FILE, FALSE) != FPC_SAME
  1285. #endif
  1286.                 )
  1287.         i = do_source((char_u *)VIMRC_FILE, TRUE, TRUE);
  1288.  
  1289.         if (i == FAIL)
  1290.         {
  1291. #if defined(UNIX) || defined(VMS)
  1292.         /* if ".exrc" is not owned by user set 'secure' mode */
  1293.         if (!file_owned(EXRC_FILE))
  1294.             secure = p_secure;
  1295.         else
  1296.             secure = 0;
  1297. #endif
  1298.         if (       fullpathcmp((char_u *)USR_EXRC_FILE,
  1299.                       (char_u *)EXRC_FILE, FALSE) != FPC_SAME
  1300. #ifdef USR_EXRC_FILE2
  1301.             && fullpathcmp((char_u *)USR_EXRC_FILE2,
  1302.                       (char_u *)EXRC_FILE, FALSE) != FPC_SAME
  1303. #endif
  1304.                 )
  1305.             (void)do_source((char_u *)EXRC_FILE, FALSE, FALSE);
  1306.         }
  1307.     }
  1308.     if (secure == 2)
  1309.         need_wait_return = TRUE;
  1310.     secure = 0;
  1311. #ifdef AMIGA
  1312.     proc->pr_WindowPtr = save_winptr;
  1313. #endif
  1314.     }
  1315.     TIME_MSG("sourcing vimrc file(s)");
  1316.  
  1317. #ifdef FEAT_EVAL
  1318.     /*
  1319.      * Read all the plugin files.
  1320.      * Only when compiled with +eval, since most plugins need it.
  1321.      */
  1322.     if (p_lpl)
  1323.     {
  1324.     cmd_runtime((char_u *)"plugin/*.vim", TRUE);
  1325.     TIME_MSG("loading plugins");
  1326.     }
  1327. #endif
  1328.  
  1329.     /*
  1330.      * Recovery mode without a file name: List swap files.
  1331.      * This uses the 'dir' option, therefore it must be after the
  1332.      * initializations.
  1333.      */
  1334.     if (recoverymode && fname == NULL)
  1335.     {
  1336.     recover_names(NULL, TRUE, 0);
  1337.     mch_exit(0);
  1338.     }
  1339.  
  1340.     /*
  1341.      * Set a few option defaults after reading .vimrc files:
  1342.      * 'title' and 'icon', Unix: 'shellpipe' and 'shellredir'.
  1343.      */
  1344.     set_init_3();
  1345.     TIME_MSG("inits 3");
  1346.  
  1347.     /*
  1348.      * "-n" argument: Disable swap file by setting 'updatecount' to 0.
  1349.      * Note that this overrides anything from a vimrc file.
  1350.      */
  1351.     if (no_swap_file)
  1352.     p_uc = 0;
  1353.  
  1354. #ifdef FEAT_FKMAP
  1355.     if (curwin->w_p_rl && p_altkeymap)
  1356.     {
  1357.     p_hkmap = FALSE;    /* Reset the Hebrew keymap mode */
  1358.     p_fkmap = TRUE;        /* Set the Farsi keymap mode */
  1359.     }
  1360. #endif
  1361.  
  1362. #ifdef FEAT_GUI
  1363.     if (gui.starting)
  1364.     {
  1365.     gui_start();        /* will set full_screen to TRUE */
  1366.     TIME_MSG("starting GUI");
  1367.     }
  1368. #endif
  1369.  
  1370. #ifdef SPAWNO        /* special MSDOS swapping library */
  1371.     init_SPAWNO("", SWAP_ANY);
  1372. #endif
  1373.  
  1374. #ifdef FEAT_VIMINFO
  1375.     /*
  1376.      * Read in registers, history etc, but not marks, from the viminfo file
  1377.      */
  1378.     if (*p_viminfo != NUL)
  1379.     {
  1380.     read_viminfo(NULL, TRUE, FALSE, FALSE);
  1381.     TIME_MSG("reading viminfo");
  1382.     }
  1383. #endif
  1384.  
  1385. #ifdef FEAT_QUICKFIX
  1386.     /*
  1387.      * "-q errorfile": Load the error file now.
  1388.      * If the error file can't be read, exit before doing anything else.
  1389.      */
  1390.     if (edit_type == EDIT_QF)
  1391.     {
  1392.     if (use_ef != NULL)
  1393.         set_string_option_direct((char_u *)"ef", -1, use_ef, OPT_FREE);
  1394.     if (qf_init(p_ef, p_efm, TRUE) < 0)
  1395.     {
  1396.         out_char('\n');
  1397.         mch_exit(3);
  1398.     }
  1399.     TIME_MSG("reading errorfile");
  1400.     }
  1401. #endif
  1402.  
  1403.     /*
  1404.      * Start putting things on the screen.
  1405.      * Scroll screen down before drawing over it
  1406.      * Clear screen now, so file message will not be cleared.
  1407.      */
  1408.     starting = NO_BUFFERS;
  1409.     no_wait_return = FALSE;
  1410.     if (!exmode_active)
  1411.     msg_scroll = FALSE;
  1412.  
  1413. #ifdef FEAT_GUI
  1414.     /*
  1415.      * This seems to be required to make callbacks to be called now, instead
  1416.      * of after things have been put on the screen, which then may be deleted
  1417.      * when getting a resize callback.
  1418.      */
  1419.     if (gui.in_use)
  1420.     {
  1421. # ifdef FEAT_SUN_WORKSHOP
  1422.     if (!usingSunWorkShop)
  1423. # endif
  1424.         gui_wait_for_chars(50L);
  1425.     TIME_MSG("GUI delay");
  1426.     }
  1427. #endif
  1428.  
  1429. #ifdef FEAT_XCLIPBOARD
  1430.     /* Start using the X clipboard, unless the GUI was started. */
  1431. # ifdef FEAT_GUI
  1432.     if (!gui.in_use)
  1433. # endif
  1434.     {
  1435.     setup_term_clip();
  1436.     TIME_MSG("setup clipboard");
  1437.     }
  1438. #endif
  1439.  
  1440. #if defined(FEAT_CLIENTSERVER) && defined(FEAT_X11)
  1441.     /*
  1442.      * Register for remote command execution with :serversend and --remote
  1443.      * unless there was a -X or a --servername '' on the command line.
  1444.      * Only register nongui-vim's with an explicit --servername argument.
  1445.      */
  1446.     if (X_DISPLAY != NULL && servername != NULL && (
  1447. # ifdef FEAT_GUI
  1448.         gui.in_use ||
  1449. # endif
  1450.         serverName_arg != NULL))
  1451.     {
  1452.     (void)serverRegisterName(X_DISPLAY, servername);
  1453.     vim_free(servername);
  1454.     }
  1455.     else
  1456.     serverDelayedStartName = servername;
  1457. #endif
  1458.  
  1459. #ifdef FEAT_CLIENTSERVER
  1460.     /*
  1461.      * Execute command ourselves if we're here because the send failed (or
  1462.      * else we would have exited above).
  1463.      */
  1464.     if (serverStr != NULL)
  1465.     server_to_input_buf(serverStr);
  1466. #endif
  1467.  
  1468.     /*
  1469.      * If "-" argument given: Read file from stdin.
  1470.      * Do this before starting Raw mode, because it may change things that the
  1471.      * writing end of the pipe doesn't like, e.g., in case stdin and stderr
  1472.      * are the same terminal: "cat | vim -".
  1473.      * Using autocommands here may cause trouble...
  1474.      */
  1475.     if (edit_type == EDIT_STDIN && !recoverymode)
  1476.     {
  1477. #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
  1478.     /* When getting the ATTENTION prompt here, use a dialog */
  1479.     swap_exists_action = SEA_DIALOG;
  1480. #endif
  1481.     no_wait_return = TRUE;
  1482.     i = msg_didany;
  1483.     set_buflisted(TRUE);
  1484.     (void)open_buffer(TRUE, NULL);    /* create memfile and read file */
  1485.     no_wait_return = FALSE;
  1486.     msg_didany = i;
  1487.     TIME_MSG("reading stdin");
  1488. #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
  1489.     check_swap_exists_action();
  1490. #endif
  1491. #if !(defined(AMIGA) || defined(MACOS))
  1492.     /*
  1493.      * Close stdin and dup it from stderr.  Required for GPM to work
  1494.      * properly, and for running external commands.
  1495.      * Is there any other system that cannot do this?
  1496.      */
  1497.     close(0);
  1498.     dup(2);
  1499. #endif
  1500.     }
  1501.  
  1502.     /*
  1503.      * When done something that is not allowed or error message call
  1504.      * wait_return.  This must be done before starttermcap(), because it may
  1505.      * switch to another screen. It must be done after settmode(TMODE_RAW),
  1506.      * because we want to react on a single key stroke.
  1507.      * Call settmode and starttermcap here, so the T_KS and T_TI may be
  1508.      * defined by termcapinit and redifined in .exrc.
  1509.      */
  1510.     settmode(TMODE_RAW);
  1511.     if (need_wait_return || msg_didany)
  1512.     {
  1513.     wait_return(TRUE);
  1514.     TIME_MSG("waiting for return");
  1515.     }
  1516.  
  1517.     starttermcap();        /* start termcap if not done by wait_return() */
  1518. #ifdef FEAT_MOUSE
  1519.     setmouse();                /* may start using the mouse */
  1520. #endif
  1521.     if (scroll_region)
  1522.     scroll_region_reset();        /* In case Rows changed */
  1523.  
  1524.     scroll_start();
  1525.  
  1526.     /*
  1527.      * Don't clear the screen when starting in Ex mode, unless using the GUI.
  1528.      */
  1529.     if (exmode_active
  1530. #ifdef FEAT_GUI
  1531.             && !gui.in_use
  1532. #endif
  1533.                     )
  1534.     must_redraw = CLEAR;
  1535.     else
  1536.     {
  1537.     screenclear();            /* clear screen */
  1538.     TIME_MSG("clearing screen");
  1539.     }
  1540.  
  1541. #ifdef FEAT_CRYPT
  1542.     if (ask_for_key)
  1543.     {
  1544.     (void)get_crypt_key(TRUE, TRUE);
  1545.     TIME_MSG("getting crypt key");
  1546.     }
  1547. #endif
  1548.  
  1549.     no_wait_return = TRUE;
  1550.  
  1551. #ifdef FEAT_WINDOWS
  1552.     /*
  1553.      * Create the number of windows that was requested.
  1554.      */
  1555.     if (window_count == -1)    /* was not set */
  1556.     window_count = 1;
  1557.     if (window_count == 0)
  1558.     window_count = GARGCOUNT;
  1559.     if (window_count > 1)
  1560.     {
  1561.     /* Don't change the windows if there was a command in .vimrc that
  1562.      * already split some windows */
  1563.     if (vert_windows == MAYBE)
  1564.         vert_windows = FALSE;
  1565.     if (firstwin->w_next == NULL)
  1566.     {
  1567.         window_count = make_windows(window_count, vert_windows);
  1568.         TIME_MSG("making windows");
  1569.     }
  1570.     else
  1571.         window_count = win_count();
  1572.     }
  1573.     else
  1574.     window_count = 1;
  1575. #endif
  1576.  
  1577.     if (recoverymode)            /* do recover */
  1578.     {
  1579.     msg_scroll = TRUE;        /* scroll message up */
  1580.     ml_recover();
  1581.     msg_scroll = FALSE;
  1582.     if (curbuf->b_ml.ml_mfp == NULL) /* failed */
  1583.         getout(1);
  1584.     do_modelines();            /* do modelines */
  1585.     }
  1586.     else
  1587.     {
  1588.     /*
  1589.      * Open a buffer for windows that don't have one yet.
  1590.      * Commands in the .vimrc might have loaded a file or split the window.
  1591.      * Watch out for autocommands that delete a window.
  1592.      */
  1593. #ifdef FEAT_AUTOCMD
  1594.     /*
  1595.      * Don't execute Win/Buf Enter/Leave autocommands here
  1596.      */
  1597.     ++autocmd_no_enter;
  1598.     ++autocmd_no_leave;
  1599. #endif
  1600. #ifdef FEAT_WINDOWS
  1601.     for (curwin = firstwin; curwin != NULL; curwin = W_NEXT(curwin))
  1602. #endif
  1603.     {
  1604.         curbuf = curwin->w_buffer;
  1605.         if (curbuf->b_ml.ml_mfp == NULL)
  1606.         {
  1607. #ifdef FEAT_FOLDING
  1608.         /* Set 'foldlevel' to 'foldlevelstart' if it's not negative. */
  1609.         if (p_fdls >= 0)
  1610.             curwin->w_p_fdl = p_fdls;
  1611. #endif
  1612. #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
  1613.         /* When getting the ATTENTION prompt here, use a dialog */
  1614.         swap_exists_action = SEA_DIALOG;
  1615. #endif
  1616.         set_buflisted(TRUE);
  1617.         (void)open_buffer(FALSE, NULL); /* create memfile, read file */
  1618.  
  1619. #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
  1620.         check_swap_exists_action();
  1621. #endif
  1622. #ifdef FEAT_AUTOCMD
  1623.         curwin = firstwin;        /* start again */
  1624. #endif
  1625.         }
  1626. #ifdef FEAT_WINDOWS
  1627.         ui_breakcheck();
  1628.         if (got_int)
  1629.         {
  1630.         (void)vgetc();    /* only break the file loading, not the rest */
  1631.         break;
  1632.         }
  1633. #endif
  1634.     }
  1635. #ifdef FEAT_AUTOCMD
  1636.     --autocmd_no_enter;
  1637.     --autocmd_no_leave;
  1638. #endif
  1639. #ifdef FEAT_WINDOWS
  1640.     curwin = firstwin;
  1641.     curbuf = curwin->w_buffer;
  1642. #endif
  1643.     }
  1644.     TIME_MSG("opening buffers");
  1645.  
  1646.     /* Ex starts at last line of the file */
  1647.     if (exmode_active)
  1648.     curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
  1649.  
  1650. #ifdef FEAT_AUTOCMD
  1651.     apply_autocmds(EVENT_BUFENTER, NULL, NULL, FALSE, curbuf);
  1652.     TIME_MSG("BufEnter autocommands");
  1653. #endif
  1654.     setpcmark();
  1655.  
  1656. #ifdef FEAT_QUICKFIX
  1657.     /*
  1658.      * When started with "-q errorfile" jump to first error now.
  1659.      */
  1660.     if (edit_type == EDIT_QF)
  1661.     {
  1662.     qf_jump(0, 0, FALSE);
  1663.     TIME_MSG("jump to first error");
  1664.     }
  1665. #endif
  1666.  
  1667. #ifdef FEAT_WINDOWS
  1668.     /*
  1669.      * If opened more than one window, start editing files in the other
  1670.      * windows.  Make_windows() has already opened the windows.
  1671.      */
  1672. # ifdef FEAT_AUTOCMD
  1673.     /*
  1674.      * Don't execute Win/Buf Enter/Leave autocommands here
  1675.      */
  1676.     ++autocmd_no_enter;
  1677.     ++autocmd_no_leave;
  1678. # endif
  1679.     arg_idx = 1;
  1680.     for (i = 1; i < window_count; ++i)
  1681.     {
  1682.     if (curwin->w_next == NULL)        /* just checking */
  1683.         break;
  1684.     win_enter(curwin->w_next, FALSE);
  1685.  
  1686.     /* Only open the file if there is no file in this window yet (that can
  1687.      * happen when .vimrc contains ":sall") */
  1688.     if (curbuf == firstwin->w_buffer || curbuf->b_ffname == NULL)
  1689.     {
  1690.         curwin->w_arg_idx = arg_idx;
  1691.         /* edit file from arg list, if there is one */
  1692.         (void)do_ecmd(0, arg_idx < GARGCOUNT
  1693.               ? alist_name(&GARGLIST[arg_idx]) : NULL,
  1694.               NULL, NULL, ECMD_LASTL, ECMD_HIDE);
  1695.         if (arg_idx == GARGCOUNT - 1)
  1696.         arg_had_last = TRUE;
  1697.         ++arg_idx;
  1698.     }
  1699.     ui_breakcheck();
  1700.     if (got_int)
  1701.     {
  1702.         (void)vgetc();    /* only break the file loading, not the rest */
  1703.         break;
  1704.     }
  1705.     }
  1706. # ifdef FEAT_AUTOCMD
  1707.     --autocmd_no_enter;
  1708. # endif
  1709.     win_enter(firstwin, FALSE);        /* back to first window */
  1710. # ifdef FEAT_AUTOCMD
  1711.     --autocmd_no_leave;
  1712. # endif
  1713.     TIME_MSG("editing files in windows");
  1714.     if (window_count > 1)
  1715.     win_equal(curwin, 'b');        /* adjust heights */
  1716. #endif /* FEAT_WINDOWS */
  1717.  
  1718. #ifdef FEAT_DIFF
  1719.     if (diff_mode)
  1720.     {
  1721.     win_T    *wp;
  1722.  
  1723.     /* set options in each window for "vimdiff". */
  1724.     for (wp = firstwin; wp != NULL; wp = wp->w_next)
  1725.         diff_win_options(wp, TRUE);
  1726.     }
  1727. #endif
  1728.  
  1729.     /*
  1730.      * Shorten any of the filenames, but only when absolute.
  1731.      */
  1732.     shorten_fnames(FALSE);
  1733.  
  1734.     /*
  1735.      * Need to jump to the tag before executing the '-c command'.
  1736.      * Makes "vim -c '/return' -t main" work.
  1737.      */
  1738.     if (tagname)
  1739.     {
  1740.     STRCPY(IObuff, "ta ");
  1741.  
  1742.     STRNCAT(IObuff, tagname, IOSIZE - 4);
  1743.     IObuff[IOSIZE - 1] = NUL;
  1744.     do_cmdline_cmd(IObuff);
  1745.     TIME_MSG("jumping to tag");
  1746.     }
  1747.  
  1748.     if (n_commands > 0)
  1749.     {
  1750.     /*
  1751.      * We start commands on line 0, make "vim +/pat file" match a
  1752.      * pattern on line 1.
  1753.      */
  1754.     msg_scroll = TRUE;
  1755.     curwin->w_cursor.lnum = 0;
  1756.     sourcing_name = (char_u *)"command line";
  1757.     for (i = 0; i < n_commands; ++i)
  1758.         do_cmdline_cmd(commands[i]);
  1759.     sourcing_name = NULL;
  1760.     if (curwin->w_cursor.lnum == 0)
  1761.         curwin->w_cursor.lnum = 1;
  1762.  
  1763.     if (!exmode_active)
  1764.         msg_scroll = FALSE;
  1765.  
  1766. #ifdef FEAT_QUICKFIX
  1767.     /* When started with "-q errorfile" jump to first again. */
  1768.     if (edit_type == EDIT_QF)
  1769.         qf_jump(0, 0, FALSE);
  1770. #endif
  1771.     TIME_MSG("executing command arguments");
  1772.     }
  1773.  
  1774.     RedrawingDisabled = 0;
  1775.     redraw_all_later(NOT_VALID);
  1776.     no_wait_return = FALSE;
  1777.     starting = 0;
  1778.  
  1779.     /* start in insert mode */
  1780.     if (p_im)
  1781.     need_start_insertmode = TRUE;
  1782.  
  1783. #ifdef FEAT_AUTOCMD
  1784.     apply_autocmds(EVENT_VIMENTER, NULL, NULL, FALSE, curbuf);
  1785.     TIME_MSG("VimEnter autocommands");
  1786. #endif
  1787.  
  1788. #if defined(FEAT_DIFF) && defined(FEAT_SCROLLBIND)
  1789.     /* When a startup script or session file setup for diff'ing and
  1790.      * scrollbind, sync the scrollbind now. */
  1791.     if (curwin->w_p_diff && curwin->w_p_scb)
  1792.     {
  1793.     update_topline();
  1794.     check_scrollbind((linenr_T)0, 0L);
  1795.     TIME_MSG("diff scrollbinding");
  1796.     }
  1797. #endif
  1798.  
  1799. #if defined(WIN3264) && !defined(FEAT_GUI_W32)
  1800.     mch_set_winsize_now();        /* Allow winsize changes from now on */
  1801. #endif
  1802.  
  1803.     /* If ":startinsert" command used, stuff a dummy command to be able to
  1804.      * call normal_cmd(), which will then start Insert mode. */
  1805.     if (restart_edit != 0)
  1806.     stuffcharReadbuff(K_IGNORE);
  1807.  
  1808.     TIME_MSG("before starting main loop");
  1809.  
  1810.     /*
  1811.      * Call the main command loop.  This never returns.
  1812.      */
  1813.     main_loop(FALSE);
  1814.  
  1815.     return 0;
  1816. }
  1817. #endif /* PROTO */
  1818.  
  1819. /*
  1820.  * Main loop: Execute Normal mode commands until exiting Vim.
  1821.  * Also used to handle commands in the command-line window, until the window
  1822.  * is closed.
  1823.  */
  1824.     void
  1825. main_loop(cmdwin)
  1826.     int        cmdwin;    /* TRUE when working in the command-line window */
  1827. {
  1828.     oparg_T    oa;    /* operator arguments */
  1829.  
  1830.     clear_oparg(&oa);
  1831.     while (!cmdwin
  1832. #ifdef FEAT_CMDWIN
  1833.         || cmdwin_result == 0
  1834. #endif
  1835.         )
  1836.     {
  1837.     if (stuff_empty())
  1838.     {
  1839.         did_check_timestamps = FALSE;
  1840.         if (need_check_timestamps)
  1841.         check_timestamps(FALSE);
  1842.         if (need_wait_return)    /* if wait_return still needed ... */
  1843.         wait_return(FALSE);    /* ... call it now */
  1844.         if (need_start_insertmode && goto_im())
  1845.         {
  1846.         need_start_insertmode = FALSE;
  1847.         stuffReadbuff((char_u *)"i");    /* start insert mode next */
  1848.         /* skip the fileinfo message now, because it would be shown
  1849.          * after insert mode finishes! */
  1850.         need_fileinfo = FALSE;
  1851.         }
  1852.     }
  1853.     if (got_int && !global_busy)
  1854.     {
  1855.         if (!quit_more)
  1856.         (void)vgetc();        /* flush all buffers */
  1857.         got_int = FALSE;
  1858.     }
  1859.     if (!exmode_active)
  1860.         msg_scroll = FALSE;
  1861.     quit_more = FALSE;
  1862.  
  1863.     /*
  1864.      * If skip redraw is set (for ":" in wait_return()), don't redraw now.
  1865.      * If there is nothing in the stuff_buffer or do_redraw is TRUE,
  1866.      * update cursor and redraw.
  1867.      */
  1868.     if (skip_redraw || exmode_active)
  1869.         skip_redraw = FALSE;
  1870.     else if (do_redraw || stuff_empty())
  1871.     {
  1872. #if defined(FEAT_FOLDING) && defined(FEAT_VISUAL)
  1873.         /* Include a closed fold completely in the Visual area. */
  1874.         foldAdjustVisual();
  1875. #endif
  1876. #ifdef FEAT_FOLDING
  1877.         /*
  1878.          * When 'foldclose' is set, apply 'foldlevel' to folds that don't
  1879.          * contain the cursor.
  1880.          * When 'foldopen' is "all", open the fold(s) under the cursor.
  1881.          * This may mark the window for redrawing.
  1882.          */
  1883.         if (hasAnyFolding(curwin) && !char_avail())
  1884.         {
  1885.         foldCheckClose();
  1886.         if (fdo_flags & FDO_ALL)
  1887.             foldOpenCursor();
  1888.         }
  1889. #endif
  1890.  
  1891.         /*
  1892.          * Before redrawing, make sure w_topline is correct, and w_leftcol
  1893.          * if lines don't wrap, and w_skipcol if lines wrap.
  1894.          */
  1895.         update_topline();
  1896.         validate_cursor();
  1897.  
  1898. #ifdef FEAT_VISUAL
  1899.         if (VIsual_active)
  1900.         update_curbuf(INVERTED);/* update inverted part */
  1901.         else
  1902. #endif
  1903.         if (must_redraw)
  1904.         update_screen(0);
  1905.         else if (redraw_cmdline || clear_cmdline)
  1906.         showmode();
  1907. #ifdef FEAT_WINDOWS
  1908.         redraw_statuslines();
  1909. #endif
  1910. #ifdef FEAT_TITLE
  1911.         if (need_maketitle)
  1912.         maketitle();
  1913. #endif
  1914.         /* display message after redraw */
  1915.         if (keep_msg != NULL)
  1916.         {
  1917.         char_u *p;
  1918.  
  1919.         /* msg_attr_keep() will set keep_msg to NULL, must free the
  1920.          * string here. */
  1921.         p = keep_msg;
  1922.         msg_attr(p, keep_msg_attr);
  1923.         vim_free(p);
  1924.         }
  1925.         if (need_fileinfo)        /* show file info after redraw */
  1926.         {
  1927.         fileinfo(FALSE, TRUE, FALSE);
  1928.         need_fileinfo = FALSE;
  1929.         }
  1930.  
  1931.         emsg_on_display = FALSE;    /* can delete error message now */
  1932.         did_emsg = FALSE;
  1933.         msg_didany = FALSE;        /* reset lines_left in msg_start() */
  1934.         do_redraw = FALSE;
  1935.         showruler(FALSE);
  1936.  
  1937.         setcursor();
  1938.         cursor_on();
  1939.     }
  1940. #ifdef FEAT_GUI
  1941.     if (need_mouse_correct)
  1942.         gui_mouse_correct();
  1943. #endif
  1944.  
  1945.     /*
  1946.      * Update w_curswant if w_set_curswant has been set.
  1947.      * Postponed until here to avoid computing w_virtcol too often.
  1948.      */
  1949.     update_curswant();
  1950.  
  1951.     /*
  1952.      * If we're invoked as ex, do a round of ex commands.
  1953.      * Otherwise, get and execute a normal mode command.
  1954.      */
  1955.     if (exmode_active)
  1956.         do_exmode(exmode_active == EXMODE_VIM);
  1957.     else
  1958.         normal_cmd(&oa, TRUE);
  1959.     }
  1960. }
  1961.  
  1962.     void
  1963. getout(exitval)
  1964.     int        exitval;
  1965. {
  1966. #ifdef FEAT_AUTOCMD
  1967.     buf_T    *buf;
  1968.     win_T    *wp;
  1969. #endif
  1970.  
  1971.     exiting = TRUE;
  1972.  
  1973.     /* Position the cursor on the last screen line, below all the text */
  1974. #ifdef FEAT_GUI
  1975.     if (!gui.in_use)
  1976. #endif
  1977.     windgoto((int)Rows - 1, 0);
  1978.  
  1979. #ifdef FEAT_AUTOCMD
  1980.     /* Trigger BufWinLeave for all windows, but only once per buffer. */
  1981.     for (wp = firstwin; wp != NULL; )
  1982.     {
  1983.     buf = wp->w_buffer;
  1984.     if (buf->b_changedtick != -1)
  1985.     {
  1986.         apply_autocmds(EVENT_BUFWINLEAVE, buf->b_fname, buf->b_fname,
  1987.                                   FALSE, buf);
  1988.         buf->b_changedtick = -1;    /* note that we did it already */
  1989.         wp = firstwin;        /* restart, window may be closed */
  1990.     }
  1991.     else
  1992.         wp = wp->w_next;
  1993.     }
  1994.     /* Trigger BufUnload for buffers that are loaded */
  1995.     for (buf = firstbuf; buf != NULL; buf = buf->b_next)
  1996.     if (buf->b_ml.ml_mfp != NULL)
  1997.     {
  1998.         apply_autocmds(EVENT_BUFUNLOAD, buf->b_fname, buf->b_fname,
  1999.                                   FALSE, buf);
  2000.         if (!buf_valid(buf))    /* autocmd may delete the buffer */
  2001.         break;
  2002.     }
  2003.     apply_autocmds(EVENT_VIMLEAVEPRE, NULL, NULL, FALSE, curbuf);
  2004. #endif
  2005.  
  2006. #ifdef FEAT_VIMINFO
  2007.     if (*p_viminfo != NUL)
  2008.     {
  2009.     /* Write out the registers, history, marks etc, to the viminfo file */
  2010.     msg_didany = FALSE;
  2011.     write_viminfo(NULL, FALSE);
  2012.     if (msg_didany)        /* make the user read the error message */
  2013.     {
  2014.         no_wait_return = FALSE;
  2015.         wait_return(FALSE);
  2016.     }
  2017.     }
  2018. #endif /* FEAT_VIMINFO */
  2019.  
  2020. #ifdef FEAT_AUTOCMD
  2021.     apply_autocmds(EVENT_VIMLEAVE, NULL, NULL, FALSE, curbuf);
  2022.  
  2023.     /* Position the cursor again, the autocommands may have moved it */
  2024. # ifdef FEAT_GUI
  2025.     if (!gui.in_use)
  2026. # endif
  2027.     windgoto((int)Rows - 1, 0);
  2028. #endif
  2029.  
  2030. #ifdef FEAT_TCL
  2031.     tcl_end();
  2032. #endif
  2033. #ifdef FEAT_RUBY
  2034.     ruby_end();
  2035. #endif
  2036. #ifdef FEAT_PYTHON
  2037.     python_end();
  2038. #endif
  2039. #ifdef FEAT_PERL
  2040.     perl_end();
  2041. #endif
  2042. #if defined(USE_ICONV) && defined(DYNAMIC_ICONV)
  2043.     iconv_end();
  2044. #endif
  2045.  
  2046.     mch_exit(exitval);
  2047. }
  2048.  
  2049. /*
  2050.  * Get a (optional) count for a Vim argument.
  2051.  */
  2052.     static int
  2053. get_number_arg(p, idx, def)
  2054.     char_u    *p;        /* pointer to argument */
  2055.     int        *idx;        /* index in argument, is incremented */
  2056.     int        def;        /* default value */
  2057. {
  2058.     if (isdigit(p[*idx]))
  2059.     {
  2060.     def = atoi((char *)&(p[*idx]));
  2061.     while (isdigit(p[*idx]))
  2062.         *idx = *idx + 1;
  2063.     }
  2064.     return def;
  2065. }
  2066.  
  2067. /*
  2068.  * Setup to start using the GUI.  Exit with an error when not available.
  2069.  */
  2070.     static void
  2071. main_start_gui()
  2072. {
  2073. #ifdef FEAT_GUI
  2074.     gui.starting = TRUE;    /* start GUI a bit later */
  2075. #else
  2076.     mch_errmsg(_(e_nogvim));
  2077.     mch_errmsg("\n");
  2078.     mch_exit(2);
  2079. #endif
  2080. }
  2081.  
  2082. /*
  2083.  * Get an evironment variable, and execute it as Ex commands.
  2084.  * Returns FAIL if the environment variable was not executed, OK otherwise.
  2085.  */
  2086.     int
  2087. process_env(env, is_viminit)
  2088.     char_u    *env;
  2089.     int        is_viminit; /* when TRUE, called for VIMINIT */
  2090. {
  2091.     char_u    *initstr;
  2092.     char_u    *save_sourcing_name;
  2093.     linenr_T    save_sourcing_lnum;
  2094.  
  2095.     if ((initstr = mch_getenv(env)) != NULL && *initstr != NUL)
  2096.     {
  2097.     if (is_viminit)
  2098.         vimrc_found();
  2099.     save_sourcing_name = sourcing_name;
  2100.     save_sourcing_lnum = sourcing_lnum;
  2101.     sourcing_name = env;
  2102.     sourcing_lnum = 0;
  2103.     do_cmdline_cmd(initstr);
  2104.     sourcing_name = save_sourcing_name;
  2105.     sourcing_lnum = save_sourcing_lnum;
  2106.     return OK;
  2107.     }
  2108.     return FAIL;
  2109. }
  2110.  
  2111. #if defined(UNIX) || defined(VMS)
  2112. /*
  2113.  * Return TRUE if we are certain the user owns the file "fname".
  2114.  * Used for ".vimrc" and ".exrc".
  2115.  * Use both stat() and lstat() for extra security.
  2116.  */
  2117.     static int
  2118. file_owned(fname)
  2119.     char    *fname;
  2120. {
  2121.     struct stat s;
  2122. # ifdef UNIX
  2123.     uid_t    uid = getuid();
  2124. # else     /* VMS */
  2125.     uid_t    uid = ((getgid() << 16) | getuid());
  2126. # endif
  2127.  
  2128.     return !(mch_stat(fname, &s) != 0 || s.st_uid != uid
  2129. # ifdef HAVE_LSTAT
  2130.         || mch_lstat(fname, &s) != 0 || s.st_uid != uid
  2131. # endif
  2132.         );
  2133. }
  2134. #endif
  2135.  
  2136. /*
  2137.  * Give an error message main_errors["n"] and exit.
  2138.  */
  2139.     static void
  2140. mainerr(n, str)
  2141.     int        n;    /* one of the ME_ defines */
  2142.     char_u    *str;    /* extra argument or NULL */
  2143. {
  2144. #if defined(UNIX) || defined(__EMX__) || defined(VMS)
  2145.     reset_signals();        /* kill us with CTRL-C here, if you like */
  2146. #endif
  2147.  
  2148.     mch_errmsg(longVersion);
  2149.     mch_errmsg("\n");
  2150.     mch_errmsg(_(main_errors[n]));
  2151.     if (str != NULL)
  2152.     {
  2153.     mch_errmsg(": \"");
  2154.     mch_errmsg((char *)str);
  2155.     mch_errmsg("\"");
  2156.     }
  2157.     mch_errmsg(_("\nMore info with: \"vim -h\"\n"));
  2158.  
  2159.     mch_exit(1);
  2160. }
  2161.  
  2162.     void
  2163. mainerr_arg_missing(str)
  2164.     char_u    *str;
  2165. {
  2166.     mainerr(ME_ARG_MISSING, str);
  2167. }
  2168.  
  2169. /*
  2170.  * print a message with three spaces prepended and '\n' appended.
  2171.  */
  2172.     static void
  2173. main_msg(s)
  2174.     char *s;
  2175. {
  2176.     mch_msg("   ");
  2177.     mch_msg(s);
  2178.     mch_msg("\n");
  2179. }
  2180.  
  2181. /*
  2182.  * Print messages for "vim -h" or "vim --help" and exit.
  2183.  */
  2184.     static void
  2185. usage()
  2186. {
  2187.     int        i;
  2188.     static char    *(use[]) =
  2189.     {
  2190.     N_("[file ..]       edit specified file(s)"),
  2191.     N_("-               read text from stdin"),
  2192.     N_("-t tag          edit file where tag is defined"),
  2193. #ifdef FEAT_QUICKFIX
  2194.     N_("-q [errorfile]  edit file with first error")
  2195. #endif
  2196.     };
  2197.  
  2198. #if defined(UNIX) || defined(__EMX__) || defined(VMS)
  2199.     reset_signals();        /* kill us with CTRL-C here, if you like */
  2200. #endif
  2201.  
  2202.     mch_msg(longVersion);
  2203.     mch_msg(_("\n\nusage:"));
  2204.     for (i = 0; ; ++i)
  2205.     {
  2206.     mch_msg(_(" vim [arguments] "));
  2207.     mch_msg(_(use[i]));
  2208.     if (i == (sizeof(use) / sizeof(char_u *)) - 1)
  2209.         break;
  2210.     mch_msg(_("\n   or:"));
  2211.     }
  2212.  
  2213.     mch_msg(_("\n\nArguments:\n"));
  2214.     main_msg(_("--\t\t\tOnly file names after this"));
  2215. #ifdef FEAT_OLE
  2216.     main_msg(_("-register\t\tRegister this gvim for OLE"));
  2217.     main_msg(_("-unregister\t\tUnregister gvim for OLE"));
  2218. #endif
  2219. #ifdef FEAT_GUI
  2220.     main_msg(_("-g\t\t\tRun using GUI (like \"gvim\")"));
  2221.     main_msg(_("-f\t\t\tForeground: Don't fork when starting GUI"));
  2222. #endif
  2223.     main_msg(_("-v\t\t\tVi mode (like \"vi\")"));
  2224.     main_msg(_("-e\t\t\tEx mode (like \"ex\")"));
  2225.     main_msg(_("-s\t\t\tSilent (batch) mode (only for \"ex\")"));
  2226. #ifdef FEAT_DIFF
  2227.     main_msg(_("-d\t\t\tDiff mode (like \"vimdiff\")"));
  2228. #endif
  2229.     main_msg(_("-y\t\t\tEasy mode (like \"evim\", modeless)"));
  2230.     main_msg(_("-R\t\t\tReadonly mode (like \"view\")"));
  2231.     main_msg(_("-Z\t\t\tRestricted mode (like \"rvim\")"));
  2232.     main_msg(_("-m\t\t\tModifications (writing files) not allowed"));
  2233.     main_msg(_("-M\t\t\tModifications in text not allowed"));
  2234.     main_msg(_("-b\t\t\tBinary mode"));
  2235. #ifdef FEAT_LISP
  2236.     main_msg(_("-l\t\t\tLisp mode"));
  2237. #endif
  2238.     main_msg(_("-C\t\t\tCompatible with Vi: 'compatible'"));
  2239.     main_msg(_("-N\t\t\tNot fully Vi compatible: 'nocompatible'"));
  2240.     main_msg(_("-V[N]\t\tVerbose level"));
  2241.     main_msg(_("-D\t\t\tDebugging mode"));
  2242.     main_msg(_("-n\t\t\tNo swap file, use memory only"));
  2243.     main_msg(_("-r\t\t\tList swap files and exit"));
  2244.     main_msg(_("-r (with file name)\tRecover crashed session"));
  2245.     main_msg(_("-L\t\t\tSame as -r"));
  2246. #ifdef AMIGA
  2247.     main_msg(_("-f\t\t\tDon't use newcli to open window"));
  2248.     main_msg(_("-dev <device>\t\tUse <device> for I/O"));
  2249. #endif
  2250. #ifdef FEAT_RIGHTLEFT
  2251.     main_msg(_("-H\t\t\tstart in Hebrew mode"));
  2252. #endif
  2253. #ifdef FEAT_FKMAP
  2254.     main_msg(_("-F\t\t\tstart in Farsi mode"));
  2255. #endif
  2256.     main_msg(_("-T <terminal>\tSet terminal type to <terminal>"));
  2257.     main_msg(_("-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"));
  2258. #ifdef FEAT_GUI
  2259.     main_msg(_("-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"));
  2260. #endif
  2261.     main_msg(_("--noplugin\t\tDon't load plugin scripts"));
  2262.     main_msg(_("-o[N]\t\tOpen N windows (default: one for each file)"));
  2263.     main_msg(_("-O[N]\t\tlike -o but split vertically"));
  2264.     main_msg(_("+\t\t\tStart at end of file"));
  2265.     main_msg(_("+<lnum>\t\tStart at line <lnum>"));
  2266. #ifdef FEAT_PRECOMMANDS
  2267.     main_msg(_("--cmd <command>\tExecute <command> before loading any vimrc file"));
  2268. #endif
  2269.     main_msg(_("-c <command>\t\tExecute <command> after loading the first file"));
  2270.     main_msg(_("-S <session>\t\tSource file <session> after loading the first file"));
  2271.     main_msg(_("-s <scriptin>\tRead Normal mode commands from file <scriptin>"));
  2272.     main_msg(_("-w <scriptout>\tAppend all typed commands to file <scriptout>"));
  2273.     main_msg(_("-W <scriptout>\tWrite all typed commands to file <scriptout>"));
  2274. #ifdef FEAT_CRYPT
  2275.     main_msg(_("-x\t\t\tEdit encrypted files"));
  2276. #endif
  2277. #if (defined(UNIX) || defined(VMS)) && defined(FEAT_X11)
  2278. # ifndef FEAT_GUI_X11
  2279.     main_msg(_("-display <display>\tConnect vim to this particular X-server"));
  2280. # endif
  2281.     main_msg(_("-X\t\t\tDo not connect to X server"));
  2282. # ifdef FEAT_GUI_GTK
  2283.     main_msg(_("--socketid <xid>\tOpen Vim inside another GTK widget"));
  2284. # endif
  2285. #endif
  2286. #ifdef FEAT_CLIENTSERVER
  2287.     main_msg(_("--remote <files>\tEdit <files> in a Vim server and exit"));
  2288.     main_msg(_("--remote-wait <files>  As --remote but wait for files to have been edited"));
  2289.     main_msg(_("--remote-send <keys>\tSend <keys> to a Vim server and exit"));
  2290.     main_msg(_("--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"));
  2291.     main_msg(_("--serverlist\t\tList available Vim server names and exit"));
  2292.     main_msg(_("--servername <name>\tSend to/become the Vim server <name>"));
  2293. #endif
  2294. #ifdef FEAT_VIMINFO
  2295.     main_msg(_("-i <viminfo>\t\tUse <viminfo> instead of .viminfo"));
  2296. #endif
  2297.     main_msg(_("-h\t\t\tprint Help (this message) and exit"));
  2298.     main_msg(_("--version\t\tprint version information and exit"));
  2299.  
  2300. #ifdef FEAT_GUI_X11
  2301. # ifdef FEAT_GUI_MOTIF
  2302.     mch_msg(_("\nArguments recognised by gvim (Motif version):\n"));
  2303. # else
  2304. #  ifdef FEAT_GUI_ATHENA
  2305.     mch_msg(_("\nArguments recognised by gvim (Athena version):\n"));
  2306. #  endif
  2307. # endif
  2308.     main_msg(_("-display <display>\tRun vim on <display>"));
  2309.     main_msg(_("-iconic\t\tStart vim iconified"));
  2310. # if 0
  2311.     main_msg(_("-name <name>\t\tUse resource as if vim was <name>"));
  2312.     mch_msg(_("\t\t\t  (Unimplemented)\n"));
  2313. # endif
  2314.     main_msg(_("-background <color>\tUse <color> for the background (also: -bg)"));
  2315.     main_msg(_("-foreground <color>\tUse <color> for normal text (also: -fg)"));
  2316.     main_msg(_("-font <font>\t\tUse <font> for normal text (also: -fn)"));
  2317.     main_msg(_("-boldfont <font>\tUse <font> for bold text"));
  2318.     main_msg(_("-italicfont <font>\tUse <font> for italic text"));
  2319.     main_msg(_("-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"));
  2320.     main_msg(_("-borderwidth <width>\tUse a border width of <width> (also: -bw)"));
  2321.     main_msg(_("-scrollbarwidth <width>  Use a scrollbar width of <width> (also: -sw)"));
  2322. # ifdef FEAT_GUI_ATHENA
  2323.     main_msg(_("-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"));
  2324. # endif
  2325.     main_msg(_("-reverse\t\tUse reverse video (also: -rv)"));
  2326.     main_msg(_("+reverse\t\tDon't use reverse video (also: +rv)"));
  2327.     main_msg(_("-xrm <resource>\tSet the specified resource"));
  2328. #endif /* FEAT_GUI_X11 */
  2329. #if defined(FEAT_GUI) && defined(RISCOS)
  2330.     mch_msg(_("\nArguments recognised by gvim (RISC OS version):\n"));
  2331.     main_msg(_("--columns <number>\tInitial width of window in columns"));
  2332.     main_msg(_("--rows <number>\tInitial height of window in rows"));
  2333. #endif
  2334. #ifdef FEAT_GUI_GTK
  2335.     mch_msg(_("\nArguments recognised by gvim (GTK+ version):\n"));
  2336.     main_msg(_("-font <font>\t\tUse <font> for normal text (also: -fn)"));
  2337.     main_msg(_("-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"));
  2338.     main_msg(_("-reverse\t\tUse reverse video (also: -rv)"));
  2339.     main_msg(_("-display <display>\tRun vim on <display> (also: --display)"));
  2340. # ifdef FEAT_GUI_GNOME
  2341.     main_msg(_("--help\t\tShow Gnome arguments"));
  2342. # endif
  2343. #endif
  2344.     mch_exit(1);
  2345. }
  2346.  
  2347. #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
  2348. /*
  2349.  * Check the result of the ATTENTION dialog:
  2350.  * When "Quit" selected, exit Vim.
  2351.  * When "Recover" selected, recover the file.
  2352.  */
  2353.     static void
  2354. check_swap_exists_action()
  2355. {
  2356.     if (swap_exists_action == SEA_QUIT)
  2357.     getout(1);
  2358.     handle_swap_exists(NULL);
  2359. }
  2360. #endif
  2361.  
  2362. #if defined(STARTUPTIME) || defined(PROTO)
  2363. static void time_diff __ARGS((struct timeval *then, struct timeval *now));
  2364.  
  2365. static struct timeval    prev_timeval;
  2366.  
  2367. /*
  2368.  * Save the previous time before doing something that could nest.
  2369.  * set "*tv_rel" to the time elapsed so far.
  2370.  */
  2371.     void
  2372. time_push(tv_rel, tv_start)
  2373.     void    *tv_rel, *tv_start;
  2374. {
  2375.     *((struct timeval *)tv_rel) = prev_timeval;
  2376.     gettimeofday(&prev_timeval, NULL);
  2377.     ((struct timeval *)tv_rel)->tv_usec = prev_timeval.tv_usec
  2378.                     - ((struct timeval *)tv_rel)->tv_usec;
  2379.     ((struct timeval *)tv_rel)->tv_sec = prev_timeval.tv_sec
  2380.                      - ((struct timeval *)tv_rel)->tv_sec;
  2381.     if (((struct timeval *)tv_rel)->tv_usec < 0)
  2382.     {
  2383.     ((struct timeval *)tv_rel)->tv_usec += 1000000;
  2384.     --((struct timeval *)tv_rel)->tv_sec;
  2385.     }
  2386.     *(struct timeval *)tv_start = prev_timeval;
  2387. }
  2388.  
  2389. /*
  2390.  * Compute the previous time after doing something that could nest.
  2391.  * Subtract "*tp" from prev_timeval;
  2392.  * Note: The arguments are (void *) to avoid trouble with systems that don't
  2393.  * have struct timeval.
  2394.  */
  2395.     void
  2396. time_pop(tp)
  2397.     void    *tp;    /* actually (struct timeval *) */
  2398. {
  2399.     prev_timeval.tv_usec -= ((struct timeval *)tp)->tv_usec;
  2400.     prev_timeval.tv_sec -= ((struct timeval *)tp)->tv_sec;
  2401.     if (prev_timeval.tv_usec < 0)
  2402.     {
  2403.     prev_timeval.tv_usec += 1000000;
  2404.     --prev_timeval.tv_sec;
  2405.     }
  2406. }
  2407.  
  2408.     static void
  2409. time_diff(then, now)
  2410.     struct timeval    *then;
  2411.     struct timeval    *now;
  2412. {
  2413.     long    usec;
  2414.     long    msec;
  2415.  
  2416.     usec = now->tv_usec - then->tv_usec;
  2417.     msec = (now->tv_sec - then->tv_sec) * 1000L + usec / 1000L,
  2418.     usec = usec % 1000L;
  2419.     fprintf(time_fd, "%03ld.%03ld", msec, usec >= 0 ? usec : usec + 1000L);
  2420. }
  2421.  
  2422.     void
  2423. time_msg(msg, tv_start)
  2424.     char    *msg;
  2425.     void    *tv_start;  /* only for do_source: start time; actually
  2426.                    (struct timeval *) */
  2427. {
  2428.     static struct timeval    start;
  2429.     struct timeval        now;
  2430.  
  2431.     if (time_fd != NULL)
  2432.     {
  2433.     if (strstr(msg, "STARTING") != NULL)
  2434.     {
  2435.         gettimeofday(&start, NULL);
  2436.         prev_timeval = start;
  2437.         fprintf(time_fd, "\n\ntimes in msec\n");
  2438.         fprintf(time_fd, " clock   self+sourced   self:  sourced script\n");
  2439.         fprintf(time_fd, " clock   elapsed:              other lines\n\n");
  2440.     }
  2441.     gettimeofday(&now, NULL);
  2442.     time_diff(&start, &now);
  2443.     if (((struct timeval *)tv_start) != NULL)
  2444.     {
  2445.         fprintf(time_fd, "  ");
  2446.         time_diff(((struct timeval *)tv_start), &now);
  2447.     }
  2448.     fprintf(time_fd, "  ");
  2449.     time_diff(&prev_timeval, &now);
  2450.     prev_timeval = now;
  2451.     fprintf(time_fd, ": %s\n", msg);
  2452.     }
  2453. }
  2454.  
  2455. # ifdef WIN3264
  2456. /*
  2457.  * Windows doesn't have gettimeofday(), although it does have struct timeval.
  2458.  */
  2459.     int
  2460. gettimeofday(struct timeval *tv, char *dummy)
  2461. {
  2462.     long t = clock();
  2463.     tv->tv_sec = t / CLOCKS_PER_SEC;
  2464.     tv->tv_usec = (t - tv->tv_sec * CLOCKS_PER_SEC) * 1000000 / CLOCKS_PER_SEC;
  2465.     return 0;
  2466. }
  2467. # endif
  2468.  
  2469. #endif
  2470.  
  2471. #if defined(FEAT_CLIENTSERVER) || defined(PROTO)
  2472.  
  2473. /*
  2474.  * Common code for the X command server and the Win32 command server.
  2475.  */
  2476.  
  2477. static char_u *build_drop_cmd __ARGS((int filec, char **filev, int sendReply));
  2478.  
  2479.     static void
  2480. cmdsrv_main(argc, argv, serverName_arg, serverStr)
  2481.     int        *argc;
  2482.     char    **argv;
  2483.     char_u    *serverName_arg;
  2484.     char_u    **serverStr;
  2485. {
  2486.     char_u    *res;
  2487.     int        i;
  2488.     char_u    *sname;
  2489.     int        ret;
  2490.     int        didone = FALSE;
  2491.     char    **newArgV = argv + 1;
  2492.     int        newArgC = 1,
  2493.         Argc = *argc;
  2494.     int        argtype;
  2495. #define ARGTYPE_OTHER        0
  2496. #define ARGTYPE_EDIT        1
  2497. #define ARGTYPE_EDIT_WAIT    2
  2498. #define ARGTYPE_SEND        3
  2499. # ifndef FEAT_X11
  2500.     HWND    srv;
  2501. # else
  2502.     Window    srv;
  2503.  
  2504.     setup_term_clip();
  2505. # endif
  2506.  
  2507.     sname = serverMakeName(serverName_arg, argv[0]);
  2508.     if (sname == NULL)
  2509.     return;
  2510.  
  2511. # ifdef FEAT_X11
  2512.     if (xterm_dpy != NULL)    /* Win32 always works? */
  2513. # endif
  2514.     {
  2515.     /*
  2516.      * Execute the command server related arguments and remove them
  2517.      * from the argc/argv array; We may have to return into main()
  2518.      */
  2519.     for (i = 1; i < Argc; i++)
  2520.     {
  2521.         res = NULL;
  2522.         if (STRCMP(argv[i], "--") == 0)    /* end of options */
  2523.         {
  2524.         for (; i < *argc; i++)
  2525.         {
  2526.             *newArgV++ = argv[i];
  2527.             newArgC++;
  2528.         }
  2529.         break;
  2530.         }
  2531.  
  2532.         if (STRICMP(argv[i], "--remote") == 0)
  2533.         argtype = ARGTYPE_EDIT;
  2534.         else if (STRICMP(argv[i], "--remote-wait") == 0)
  2535.         argtype = ARGTYPE_EDIT_WAIT;
  2536.         else if (STRICMP(argv[i], "--remote-send") == 0)
  2537.         argtype = ARGTYPE_SEND;
  2538.         else
  2539.         argtype = ARGTYPE_OTHER;
  2540.         if (argtype != ARGTYPE_OTHER)
  2541.         {
  2542.         if (i == *argc - 1)
  2543.             mainerr_arg_missing((char_u *)argv[i]);
  2544.         if (argtype == ARGTYPE_SEND)
  2545.         {
  2546.             *serverStr = (char_u *)argv[i + 1];
  2547.             i++;
  2548.         }
  2549.         else
  2550.         {
  2551.             *serverStr = build_drop_cmd(*argc - i - 1, argv + i + 1,
  2552.                         argv[i][8] == '-');
  2553.             Argc = i;
  2554.         }
  2555. # ifdef FEAT_X11
  2556.         ret = serverSendToVim(xterm_dpy, sname, *serverStr,
  2557.                                 NULL, &srv, 0, 0);
  2558. # else
  2559.         ret = serverSendToVim(sname, *serverStr, NULL, &srv, 0);
  2560. # endif
  2561.         if (ret < 0)
  2562.         {
  2563.             if (argtype == ARGTYPE_SEND)
  2564.             {
  2565.             /* Failed to send, abort. */
  2566.             mch_errmsg(_("\nSend failed.\n"));
  2567.             didone = TRUE;
  2568.             }
  2569.             else
  2570.             /* Let vim start normally.  */
  2571.             mch_errmsg(_("\nSend failed. Trying to execute locally\n"));
  2572.             break;
  2573.         }
  2574.  
  2575. # ifdef FEAT_GUI_W32
  2576.         /* Guess that when the server name starts with "g" it's a GUI
  2577.          * server, which we can bring to the foreground here.
  2578.          * Foreground() in the server doesn't work very well. */
  2579.         if (argtype != ARGTYPE_SEND && TO_UPPER(*sname) == 'G')
  2580.             SetForegroundWindow(srv);
  2581. # endif
  2582.  
  2583.         /*
  2584.          * For --remote-wait: Wait until the server did edit each
  2585.          * file.  Also detect that the server no longer runs.
  2586.          */
  2587.         if (ret >= 0 && argtype == ARGTYPE_EDIT_WAIT)
  2588.         {
  2589.             int        numFiles = *argc - i - 1;
  2590.             int        j;
  2591.             char_u  *done = alloc(numFiles);
  2592.             char_u  *p;
  2593. # ifdef FEAT_GUI_W32
  2594.             NOTIFYICONDATA ni;
  2595.             int count = 0;
  2596.             extern HWND message_window;
  2597.  
  2598.             ni.cbSize = sizeof(ni);
  2599.             ni.hWnd = message_window;
  2600.             ni.uID = 0;
  2601.             ni.uFlags = NIF_ICON|NIF_TIP;
  2602.             ni.hIcon = LoadIcon((HINSTANCE)GetModuleHandle(0),
  2603.                                    "IDR_VIM");
  2604.             sprintf(ni.szTip, _("%d of %d edited"), count, numFiles);
  2605.             Shell_NotifyIcon(NIM_ADD, &ni);
  2606. # endif
  2607.  
  2608.             /* Wait for all files to unload in remote */
  2609.             memset(done, 0, numFiles);
  2610.             while (memchr(done, 0, numFiles) != NULL)
  2611.             {
  2612. # ifdef WIN32
  2613.             p = serverGetReply(srv, FALSE, TRUE, TRUE);
  2614.             if (p == NULL)
  2615.                 break;
  2616. # else
  2617.             if (serverReadReply(xterm_dpy, srv, &p, TRUE) < 0)
  2618.                 break;
  2619. # endif
  2620.             j = atoi((char *)p);
  2621.             if (j >= 0 && j < numFiles)
  2622.             {
  2623. # ifdef FEAT_GUI_W32
  2624.                 ++count;
  2625.                 sprintf(ni.szTip, _("%d of %d edited"),
  2626.                                  count, numFiles);
  2627.                 Shell_NotifyIcon(NIM_MODIFY, &ni);
  2628. # endif
  2629.                 done[j] = 1;
  2630.             }
  2631.             }
  2632. # ifdef FEAT_GUI_W32
  2633.             Shell_NotifyIcon(NIM_DELETE, &ni);
  2634. # endif
  2635.         }
  2636.         }
  2637.         else if (STRICMP(argv[i], "--remote-expr") == 0)
  2638.         {
  2639.         if (i == *argc - 1)
  2640.             mainerr_arg_missing((char_u *)argv[i]);
  2641. # ifdef WIN32
  2642.         if (serverSendToVim(sname, (char_u *)argv[i + 1],
  2643.                             &res, NULL, 1) < 0)
  2644. # else
  2645.         if (serverSendToVim(xterm_dpy, sname, (char_u *)argv[i + 1],
  2646.                             &res, NULL, 1, 1) < 0)
  2647. # endif
  2648.             mch_errmsg(_("Send expression failed.\n"));
  2649.         }
  2650.         else if (STRICMP(argv[i], "--serverlist") == 0)
  2651.         {
  2652. # ifdef WIN32
  2653.         res = serverGetVimNames();
  2654. #else
  2655.         res = serverGetVimNames(xterm_dpy);
  2656. #endif
  2657.         }
  2658.         else if (STRICMP(argv[i], "--servername") == 0)
  2659.         {
  2660.         /* Alredy processed. Take it out of the command line */
  2661.         i++;
  2662.         continue;
  2663.         }
  2664.         else
  2665.         {
  2666.         *newArgV++ = argv[i];
  2667.         newArgC++;
  2668.         continue;
  2669.         }
  2670.         didone = TRUE;
  2671.         if (res != NULL && *res != NUL)
  2672.         {
  2673.         mch_msg((char *)res);
  2674.         if (res[STRLEN(res) - 1] != '\n')
  2675.             mch_msg("\n");
  2676.         }
  2677.         vim_free(res);
  2678.     }
  2679.  
  2680.     if (didone)
  2681.     {
  2682.         display_errors();    /* display any collected messages */
  2683.         exit(0);        /* Mission accomplished - get out */
  2684.     }
  2685.     }
  2686.     /* Return back into main() */
  2687.     *argc = newArgC;
  2688.     vim_free(sname);
  2689. }
  2690.  
  2691. /*
  2692.  * Build a ":drop" command to send to a Vim server.
  2693.  */
  2694.     static char_u *
  2695. build_drop_cmd(filec, filev, sendReply)
  2696.     int        filec;
  2697.     char    **filev;
  2698.     int        sendReply;
  2699. {
  2700.     garray_T    ga;
  2701.     int        i;
  2702.     char_u    *inicmd = NULL;
  2703.     char_u    *p;
  2704.     char_u    cwd[MAXPATHL];
  2705.  
  2706.     if (filec > 0 && filev[0][0] == '+')
  2707.     {
  2708.     inicmd = (char_u *)filev[0] + 1;
  2709.     filev++;
  2710.     filec--;
  2711.     }
  2712.     if (filec <= 0 || mch_dirname(cwd, MAXPATHL) != OK)
  2713.     return NULL;
  2714.     if ((p = vim_strsave_escaped(cwd, PATH_ESC_CHARS)) == NULL)
  2715.     return NULL;
  2716.     ga_init2(&ga, 1, 100);
  2717.     ga_concat(&ga, (char_u *)"<C-\\><C-N>:cd ");
  2718.     ga_concat(&ga, p);
  2719.     ga_concat(&ga, (char_u *)"<CR>:drop");
  2720.     vim_free(p);
  2721.     for (i = 0; i < filec; i++)
  2722.     {
  2723.     /* On Unix the shell has already expanded the wildcards, don't want to
  2724.      * do it again in the Vim server.  On MS-Windows only need to escape a
  2725.      * space. */
  2726.     p = vim_strsave_escaped((char_u *)filev[i],
  2727. #ifdef UNIX
  2728.         PATH_ESC_CHARS
  2729. #else
  2730.         (char_u *)" "
  2731. #endif
  2732.         );
  2733.     if (p == NULL)
  2734.     {
  2735.         vim_free(ga.ga_data);
  2736.         return NULL;
  2737.     }
  2738.     ga_concat(&ga, (char_u *)" ");
  2739.     ga_concat(&ga, p);
  2740.     vim_free(p);
  2741.     }
  2742.     ga_concat(&ga, (char_u *)"<CR>:cd -");
  2743.     if (sendReply)
  2744.     ga_concat(&ga, (char_u *)"<CR>:call SetupRemoteReplies()");
  2745.     if (inicmd != NULL)
  2746.     {
  2747.     ga_concat(&ga, (char_u *)"<CR>:");
  2748.     ga_concat(&ga, inicmd);
  2749.     }
  2750.     /* Bring the window to the foreground & clear command line */
  2751.     ga_concat(&ga, (char_u *)"<CR>:call foreground()<CR>:<CR>");
  2752.     ga_append(&ga, NUL);
  2753.     return ga.ga_data;
  2754. }
  2755.  
  2756. /*
  2757.  * Replace termcodes such as <CR> and insert as key presses if there is room.
  2758.  */
  2759.     void
  2760. server_to_input_buf(str)
  2761.     char_u    *str;
  2762. {
  2763.     char_u      *ptr = NULL;
  2764.     char_u      *cpo_save = p_cpo;
  2765.  
  2766.     /* Set 'cpoptions' the way we want it.
  2767.      *    B set - backslashes are *not* treated specially
  2768.      *    k set - keycodes are *not* reverse-engineered
  2769.      *    < unset - <Key> sequenecs *are* interpreted
  2770.      *  last parameter of replace_termcodes() is TRUE so that
  2771.      *  the <lt> sequence is recognised - needed as backslash
  2772.      *  is not special...
  2773.      */
  2774.     p_cpo = (char_u *)"Bk";
  2775.     str = replace_termcodes((char_u *)str, &ptr, FALSE, TRUE);
  2776.     p_cpo = cpo_save;
  2777.  
  2778.     add_to_input_buf(str, STRLEN(str));
  2779.     vim_free((char_u *)(ptr));
  2780. }
  2781.  
  2782. /*
  2783.  * Make our basic server name: use the specified "arg" if given, otherwise use
  2784.  * the tail of the command "cmd" we were started with.
  2785.  * Return the name in allocated memory.  This doesn't include a serial number.
  2786.  */
  2787.     static char_u *
  2788. serverMakeName(arg, cmd)
  2789.     char_u    *arg;
  2790.     char    *cmd;
  2791. {
  2792.     char_u *p;
  2793.  
  2794.     if (arg != NULL && *arg != NUL)
  2795.     p = vim_strsave_up(arg);
  2796.     else
  2797.     {
  2798.     p = vim_strsave_up(gettail((char_u *)cmd));
  2799.     /* Remove .exe or .bat from the name. */
  2800.     if (p != NULL && vim_strchr(p, '.') != NULL)
  2801.         *vim_strchr(p, '.') = NUL;
  2802.     }
  2803.     return p;
  2804. }
  2805. #endif /* FEAT_CLIENTSERVER */
  2806.  
  2807. /*
  2808.  * When FEAT_FKMAP is defined, also compile the Farsi source code.
  2809.  */
  2810. #if defined(FEAT_FKMAP) || defined(PROTO)
  2811. # include "farsi.c"
  2812. #endif
  2813.